From 871c188ecd7c350849e3450ac2af87f0311c49eb Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@suse.de>
Date: Wed, 24 Jul 2019 17:48:06 +0200
Subject: [PATCH] LDAP: Do not require START_TLS for loopback connections

If the ldap uri is resolved to a loopback address then do not require
START_TLS.

Signed-off-by: Samuel Cabrero <scabrero@suse.de>
---
 src/providers/ldap/ldap_common.c           | 23 ++++++++++++++++++++++
 src/providers/ldap/ldap_common.h           |  1 +
 src/providers/ldap/sdap_async_connection.c | 16 +++++++++++----
 3 files changed, 36 insertions(+), 4 deletions(-)

diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index cd8d2a10c7..c0fe67f4ad 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -23,6 +23,7 @@
 */
 
 #include <signal.h>
+#include <arpa/inet.h>
 
 #include "providers/ldap/ldap_common.h"
 #include "providers/fail_over.h"
@@ -792,6 +793,28 @@ bool sdap_is_secure_uri(const char *uri)
     return false;
 }
 
+bool sdap_is_loopback_address(struct sockaddr_storage *ss)
+{
+    if (ss != NULL) {
+        switch (ss->ss_family) {
+        case AF_INET:
+        {
+            struct sockaddr_in *addr = (struct sockaddr_in *)ss;
+            return (inet_netof(addr->sin_addr) == IN_LOOPBACKNET);
+        }
+        case AF_INET6:
+        {
+            struct sockaddr_in6 *addr = (struct sockaddr_in6 *)ss;
+            return IN6_IS_ADDR_LOOPBACK(&(addr->sin6_addr));
+        }
+        default:
+                break;
+        }
+    }
+
+    return false;
+}
+
 char *sdap_get_access_filter(TALLOC_CTX *mem_ctx,
                              const char *base_filter)
 {
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
index 60e3ef2974..7ca14bd1f9 100644
--- a/src/providers/ldap/ldap_common.h
+++ b/src/providers/ldap/ldap_common.h
@@ -296,6 +296,7 @@ errno_t list_missing_attrs(TALLOC_CTX *mem_ctx,
                            char ***missing_attrs);
 
 bool sdap_is_secure_uri(const char *uri);
+bool sdap_is_loopback_address(struct sockaddr_storage *ss);
 
 char *sdap_or_filters(TALLOC_CTX *mem_ctx,
                       const char *base_filter,
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
index 6bc271a912..c9a441cb30 100644
--- a/src/providers/ldap/sdap_async_connection.c
+++ b/src/providers/ldap/sdap_async_connection.c
@@ -1451,7 +1451,7 @@ static void sdap_cli_rootdse_auth_done(struct tevent_req *subreq);
 
 static errno_t
 decide_tls_usage(enum connect_tls force_tls, struct dp_option *basic,
-                 const char *uri, bool *_use_tls)
+                 struct sdap_service *service, bool *_use_tls)
 {
     bool use_tls = true;
 
@@ -1470,9 +1470,17 @@ decide_tls_usage(enum connect_tls force_tls, struct dp_option *basic,
         break;
     }
 
-    if (use_tls && sdap_is_secure_uri(uri)) {
+    if (use_tls && sdap_is_secure_uri(service->uri)) {
         DEBUG(SSSDBG_TRACE_INTERNAL,
-              "[%s] is a secure channel. No need to run START_TLS\n", uri);
+              "[%s] is a secure channel. No need to run START_TLS\n",
+              service->uri);
+        use_tls = false;
+    }
+
+    if (use_tls && sdap_is_loopback_address(service->sockaddr)) {
+        DEBUG(SSSDBG_TRACE_INTERNAL,
+              "[%s] is a loopback address. No need to run START_TLS\n",
+              service->uri);
         use_tls = false;
     }
 
@@ -1555,7 +1563,7 @@ static void sdap_cli_resolve_done(struct tevent_req *subreq)
     }
 
     ret = decide_tls_usage(state->force_tls, state->opts->basic,
-                           state->service->uri, &state->use_tls);
+                           state->service, &state->use_tls);
 
     if (ret != EOK) {
         tevent_req_error(req, EINVAL);
