diff --git a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml
index 02bdd811491..18f8903dcaa 100644
--- a/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml
+++ b/docs-xml/smbdotconf/ldap/ldapserverrequirestrongauth.xml
@@ -7,20 +7,44 @@
The defines whether
the ldap server requires ldap traffic to be signed or signed and encrypted (sealed).
- Possible values are no, allow_sasl_over_tls
+ Possible values are no,
+ allow_sasl_without_tls_channel_bindings
and yes.
- A value of no allows simple and sasl binds over
- all transports.
+ Windows has LdapEnforceChannelBinding under
+ HKLM\SYSTEM\CurrentControlSet\Services\NTDS\Parameters\.
+
- A value of allow_sasl_over_tls allows simple and sasl binds
- (without sign or seal) over TLS encrypted connections. Unencrypted connections only
- allow sasl binds with sign or seal.
+ A value of no allows simple and sasl binds over
+ all transports. This matches LdapEnforceChannelBinding=0.
+
+ A value of allow_sasl_without_tls_channel_bindings
+ allows simple and sasl binds (without sign or seal) over TLS encrypted connections.
+ Missing tls channel bindings are ignored, so only use this if a value of
+ yes is not possible.
+ Unencrypted connections only allow sasl binds with sign or seal.
+ This matches LdapEnforceChannelBinding=1.
+
+
+ Before support for tls channel bindings existed in Samba,
+ a value of allow_sasl_over_tls was possible in order
+ to allow sasl binds without tls channel bindings. This now misleading
+ as a value of yes will now allow sasl binds
+ with tls channel bindings. Configurations should be changed to
+ yes instead or
+ allow_sasl_without_tls_channel_bindings
+ if really required. Currently allow_sasl_over_tls
+ is just an alias of allow_sasl_without_tls_channel_bindings,
+ but it will be removed in future versions.
+
A value of yes allows only simple binds
- over TLS encrypted connections. Unencrypted connections only
- allow sasl binds with sign or seal.
+ and sasl binds with correct tls channel bindings
+ over TLS encrypted connections. sasl binds without tls channel bindings
+ are not allowed. Unencrypted connections only
+ allow sasl binds with sign or seal. This matches LdapEnforceChannelBinding=2.
+
yes
diff --git a/lib/param/loadparm.h b/lib/param/loadparm.h
index 0bf4c173652..7e9e5d2da3f 100644
--- a/lib/param/loadparm.h
+++ b/lib/param/loadparm.h
@@ -206,6 +206,7 @@ enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX,
enum ldap_server_require_strong_auth {
LDAP_SERVER_REQUIRE_STRONG_AUTH_NO,
LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS,
+ LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_WITHOUT_TLS_CB,
LDAP_SERVER_REQUIRE_STRONG_AUTH_YES,
};
diff --git a/lib/param/param_table.c b/lib/param/param_table.c
index ce591560ba8..8db4c381e41 100644
--- a/lib/param/param_table.c
+++ b/lib/param/param_table.c
@@ -318,6 +318,8 @@ static const struct enum_list enum_ldap_server_require_strong_auth_vals[] = {
{ LDAP_SERVER_REQUIRE_STRONG_AUTH_NO, "0" },
{ LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS,
"allow_sasl_over_tls" },
+ { LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_WITHOUT_TLS_CB,
+ "allow_sasl_without_tls_channel_bindings" },
{ LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, "Yes" },
{ LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, "True" },
{ LDAP_SERVER_REQUIRE_STRONG_AUTH_YES, "1" },
diff --git a/python/samba/netcmd/testparm.py b/python/samba/netcmd/testparm.py
index 41dbb4bd623..a419ddf1260 100644
--- a/python/samba/netcmd/testparm.py
+++ b/python/samba/netcmd/testparm.py
@@ -183,6 +183,16 @@ class cmd_testparm(Command):
"When acting as Active Directory domain controller, " +
entry + " should be in vfs objects.")
+ strong_auth = lp.get("ldap server require strong auth")
+ if strong_auth == "allow_sasl_over_tls":
+ logger.warning(
+ "WARNING: You have not configured "
+ "'ldap server require strong auth = "
+ "allow_sasl_over_tls'.\n"
+ "Please change to 'yes' (preferred) or "
+ "'allow_sasl_without_tls_channel_bindings' "
+ "(if really needed).")
+
return valid
def allow_access(self, deny_list, allow_list, cname, caddr):
diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm
index 48a78b2c8d2..f52d6740c6e 100755
--- a/selftest/target/Samba4.pm
+++ b/selftest/target/Samba4.pm
@@ -1625,7 +1625,7 @@ sub provision_ad_dc_ntvfs($$$)
print "PROVISIONING AD DC (NTVFS)...\n";
my $extra_conf_options = "netbios aliases = localDC1-a
server services = +winbind -winbindd
- ldap server require strong auth = allow_sasl_over_tls
+ ldap server require strong auth = allow_sasl_without_tls_channel_bindings
raw NTLMv2 auth = yes
lsa over netlogon = yes
rpc server port = 1027
diff --git a/source3/utils/testparm.c b/source3/utils/testparm.c
index fd90e8d734a..34bce413f82 100644
--- a/source3/utils/testparm.c
+++ b/source3/utils/testparm.c
@@ -615,6 +615,18 @@ static int do_global_checks(void)
ret = 1;
}
+ if (lp_ldap_server_require_strong_auth() ==
+ LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS)
+ {
+ fprintf(stderr,
+ "WARNING: You have not configured "
+ "'ldap server require strong auth = "
+ "allow_sasl_over_tls'.\n"
+ "Please change to 'yes' (preferred) or "
+ "'allow_sasl_without_tls_channel_bindings' "
+ "(if really needed)\n\n");
+ }
+
if (lp_server_schannel() != true) { /* can be 'auto' */
fprintf(stderr,
"WARNING: You have not configured "
diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c
index d592d472c06..65e252edb70 100644
--- a/source4/ldap_server/ldap_bind.c
+++ b/source4/ldap_server/ldap_bind.c
@@ -27,6 +27,7 @@
#include "dsdb/samdb/samdb.h"
#include "auth/gensec/gensec.h"
#include "auth/gensec/gensec_tstream.h"
+#include "lib/tls/tls.h"
#include "param/param.h"
#include "../lib/util/tevent_ntstatus.h"
#include "lib/util/time_basic.h"
@@ -359,6 +360,49 @@ static NTSTATUS ldapsrv_setup_gensec(struct ldapsrv_connection *conn,
gensec_want_feature(gensec_security, GENSEC_FEATURE_LDAP_STYLE);
if (conn->sockets.active == conn->sockets.tls) {
+ uint32_t initiator_addrtype = 0;
+ const DATA_BLOB *initiator_address = NULL;
+ uint32_t acceptor_addrtype = 0;
+ const DATA_BLOB *acceptor_address = NULL;
+ const DATA_BLOB *application_data =
+ tstream_tls_channel_bindings(conn->sockets.tls);
+
+ status = gensec_set_channel_bindings(gensec_security,
+ initiator_addrtype,
+ initiator_address,
+ acceptor_addrtype,
+ acceptor_address,
+ application_data);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /*
+ * By default channel bindings are required,
+ * so we only set GENSEC_FEATURE_CB_OPTIONAL
+ * for the legacy option:
+ *
+ * ldap server require strong auth = no
+ * or
+ * ldap server require strong auth =
+ * allow_sasl_without_tls_channel_bindings
+ *
+ * And this as an alias to cope with existing smb.conf
+ * files:
+ *
+ * ldap server require strong auth = allow_sasl_over_tls
+ */
+ switch (conn->require_strong_auth) {
+ case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO:
+ case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS:
+ case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_WITHOUT_TLS_CB:
+ gensec_want_feature(gensec_security,
+ GENSEC_FEATURE_CB_OPTIONAL);
+ break;
+ default:
+ break;
+ }
+
gensec_want_feature(gensec_security, GENSEC_FEATURE_LDAPS_TRANSPORT);
}
@@ -496,6 +540,14 @@ static void ldapsrv_BindSASL_done(struct tevent_req *subreq)
goto do_reply;
}
+ if (NT_STATUS_EQUAL(status, NT_STATUS_BAD_BINDINGS)) {
+ result = LDAP_INVALID_CREDENTIALS;
+ errstr = ldapsrv_bind_error_msg(reply,
+ HRES_SEC_E_BAD_BINDINGS,
+ 0x0C090711,
+ status);
+ goto do_reply;
+ }
if (!NT_STATUS_IS_OK(status)) {
status = nt_status_squash(status);
result = LDAP_INVALID_CREDENTIALS;
@@ -539,17 +591,11 @@ static void ldapsrv_BindSASL_done(struct tevent_req *subreq)
case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO:
break;
case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS:
+ case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_WITHOUT_TLS_CB:
+ case LDAP_SERVER_REQUIRE_STRONG_AUTH_YES:
if (call->conn->sockets.active == call->conn->sockets.tls) {
break;
}
- status = NT_STATUS_NETWORK_ACCESS_DENIED;
- result = LDAP_STRONG_AUTH_REQUIRED;
- errstr = talloc_asprintf(reply,
- "SASL:[%s]: not allowed if TLS is used.",
- req->creds.SASL.mechanism);
- goto do_reply;
-
- case LDAP_SERVER_REQUIRE_STRONG_AUTH_YES:
status = NT_STATUS_NETWORK_ACCESS_DENIED;
result = LDAP_STRONG_AUTH_REQUIRED;
errstr = talloc_asprintf(reply,
diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c
index 497d0dbc9a1..90316fd6b68 100644
--- a/source4/ldap_server/ldap_server.c
+++ b/source4/ldap_server/ldap_server.c
@@ -378,6 +378,17 @@ static void ldapsrv_accept(struct stream_connection *c,
conn->require_strong_auth = lpcfg_ldap_server_require_strong_auth(conn->lp_ctx);
}
+ if (conn->require_strong_auth ==
+ LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS)
+ {
+ D_ERR("WARNING: You have not configured "
+ "'ldap server require strong auth = "
+ "allow_sasl_over_tls'.\n"
+ "Please change to 'yes' (preferred and default) or "
+ "'allow_sasl_without_tls_channel_bindings' "
+ "(if really needed)\n\n");
+ }
+
ret = ldapsrv_backend_Init(conn, &errstring);
if (ret != LDB_SUCCESS) {
char *reason = talloc_asprintf(conn,