]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
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>
Mon, 28 Mar 2016 22:42:55 +0000 (00:42 +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 7113b63f93dd7e9118282ea37caa6027829148e5..99ca148547c76657a1efa56a965d20f432b36373 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 d849ed30bccfdc20b4ccf410aed6a7c77f1dbb8a..f4134d76bd6511c7d9c6cef88c60f708735dcab7 100644 (file)
@@ -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;
index 6f8b433a1cdabbbcef74b9538f452fe65b17796a..87a7163088182aecf6ef9b31e990c9ddd4d2cf7b 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 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;