CVE-2016-2112: s4:ldap_server: implement "ldap server require strong auth" option
authorStefan Metzmacher <metze@samba.org>
Fri, 28 Aug 2015 10:19:37 +0000 (12:19 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 12 Apr 2016 17:25:25 +0000 (19:25 +0200)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11644

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Günther Deschner <gd@samba.org>
source4/ldap_server/ldap_bind.c
source4/ldap_server/ldap_server.c
source4/ldap_server/ldap_server.h

index d1137e058c0ddb0adf96ad320839492df88a0b72..c7715de14198d9ea92e739285c71477aea2384f0 100644 (file)
@@ -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) {
index 9b2f18595fc59c5e983ebfcb008cabced14d6b98..8b21fbbe1deb9c9a7eb1ca40d66b644934f90e5b 100644 (file)
@@ -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;
index 27e0f1322bb5c7669e2d0fd3b2ab5e85aea88cf5..86e5d34f21e65f62482d2f4f3245b98f515462de 100644 (file)
@@ -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;