From: Stefan Metzmacher Date: Fri, 28 Aug 2015 10:19:37 +0000 (+0200) Subject: CVE-2016-2112: s4:ldap_server: implement "ldap server require strong auth" option X-Git-Tag: samba-4.2.10~157 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a5bedee0c34307b82a1005388bde9c69ec2ad70;p=thirdparty%2Fsamba.git CVE-2016-2112: s4:ldap_server: implement "ldap server require strong auth" option BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644 Signed-off-by: Stefan Metzmacher Reviewed-by: Günther Deschner --- diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 7113b63f93d..99ca148547c 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -45,6 +45,23 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) DEBUG(10, ("BindSimple dn: %s\n",req->dn)); + reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse); + if (!reply) { + return NT_STATUS_NO_MEMORY; + } + + if (req->dn != NULL && + strlen(req->dn) != 0 && + call->conn->require_strong_auth > LDAP_SERVER_REQUIRE_STRONG_AUTH_NO && + call->conn->sockets.active != call->conn->sockets.tls) + { + status = NT_STATUS_NETWORK_ACCESS_DENIED; + result = LDAP_STRONG_AUTH_REQUIRED; + errstr = talloc_asprintf(reply, + "BindSimple: Transport encryption required."); + goto do_reply; + } + status = crack_auto_name_to_nt4_name(call, call->conn->connection->event.ctx, call->conn->lp_ctx, req->dn, &nt4_domain, &nt4_account); if (NT_STATUS_IS_OK(status)) { status = authenticate_username_pw(call, @@ -58,11 +75,6 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) &session_info); } - reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse); - if (!reply) { - return NT_STATUS_NO_MEMORY; - } - if (NT_STATUS_IS_OK(status)) { result = LDAP_SUCCESS; errstr = NULL; @@ -86,6 +98,7 @@ static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call) errstr = talloc_asprintf(reply, "Simple Bind Failed: %s", nt_errstr(status)); } +do_reply: resp = &reply->msg->r.BindResponse; resp->response.resultcode = result; resp->response.errormessage = errstr; @@ -262,6 +275,28 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) status = NT_STATUS_NO_MEMORY; } } + } else { + switch (call->conn->require_strong_auth) { + case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO: + break; + case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS: + 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); + break; + case LDAP_SERVER_REQUIRE_STRONG_AUTH_YES: + status = NT_STATUS_NETWORK_ACCESS_DENIED; + result = LDAP_STRONG_AUTH_REQUIRED; + errstr = talloc_asprintf(reply, + "SASL:[%s]: Sign or Seal are required.", + req->creds.SASL.mechanism); + break; + } } if (result != LDAP_SUCCESS) { diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index d849ed30bcc..f4134d76bd6 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -334,6 +334,12 @@ static void ldapsrv_accept(struct stream_connection *c, conn->sockets.active = conn->sockets.raw; + if (conn->is_privileged) { + conn->require_strong_auth = LDAP_SERVER_REQUIRE_STRONG_AUTH_NO; + } else { + conn->require_strong_auth = lpcfg_ldap_server_require_strong_auth(conn->lp_ctx); + } + if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) { ldapsrv_terminate_connection(conn, "backend Init failed"); return; diff --git a/source4/ldap_server/ldap_server.h b/source4/ldap_server/ldap_server.h index 6f8b433a1cd..87a71630881 100644 --- a/source4/ldap_server/ldap_server.h +++ b/source4/ldap_server/ldap_server.h @@ -22,6 +22,7 @@ #include "lib/socket/socket.h" #include "lib/stream/packet.h" #include "system/network.h" +#include "lib/param/loadparm.h" struct ldapsrv_connection { struct loadparm_context *lp_ctx; @@ -42,6 +43,7 @@ struct ldapsrv_connection { bool global_catalog; bool is_privileged; + enum ldap_server_require_strong_auth require_strong_auth; struct { int initial_timeout;