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: talloc-2.1.7~416 X-Git-Url: http://git.samba.org/?p=samba.git;a=commitdiff_plain;h=28f1af7e50d79127fb35776488759e2e869baadb 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 d1137e058c0..c7715de1419 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 9b2f18595fc..8b21fbbe1de 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -343,6 +343,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 27e0f1322bb..86e5d34f21e 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 ldapsrv_connection *next, *prev; @@ -44,6 +45,7 @@ struct ldapsrv_connection { bool global_catalog; bool is_privileged; + enum ldap_server_require_strong_auth require_strong_auth; struct { int initial_timeout;