From f1876a046228af687b518a0b787956fed27c7d07 Mon Sep 17 00:00:00 2001
From: Adar Nimrod <nimrod@shore.co.il>
Date: Wed, 21 Apr 2021 21:28:11 +0300
Subject: [PATCH] ldapi support.

Support for using ldapi Unix socket connections. Build the connection
URI differently to suit. Added a new configuration option for specifying
the path to the socket. Don't mandate username and password if using
ldapi.

Signed-off-by: Adar Nimrod <nimrod@shore.co.il>
---
 docs/index.rst               |  2 ++
 flask_simpleldap/__init__.py | 22 ++++++++++++++++------
 2 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/docs/index.rst b/docs/index.rst
index 24b2345..0dc97d5 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -60,6 +60,8 @@ directives:
 ``LDAP_PORT``                      The port number of your LDAP server. Default: 389.
 ``LDAP_SCHEMA``                    The LDAP schema to use between 'ldap' and 'ldaps'.
                                    Default: 'ldap'.
+``LDAP_SOCKET_PATH``               If ``LDAP_SCHEMA`` is set to `ldapi`, the
+                                   path to the Unix socket path. Default: `/`.
 ``LDAP_USERNAME``                  **Required**: The user name used to bind.
 ``LDAP_PASSWORD``                  **Required**: The password used to bind.
 ``LDAP_TIMEOUT``                   How long (seconds) a connection can take to be opened
diff --git a/flask_simpleldap/__init__.py b/flask_simpleldap/__init__.py
index 1d3867d..612a223 100644
--- a/flask_simpleldap/__init__.py
+++ b/flask_simpleldap/__init__.py
@@ -34,6 +34,7 @@ class LDAP(object):
         app.config.setdefault("LDAP_HOST", "localhost")
         app.config.setdefault("LDAP_PORT", 389)
         app.config.setdefault("LDAP_SCHEMA", "ldap")
+        app.config.setdefault("LDAP_SOCKET_PATH", "/")
         app.config.setdefault("LDAP_USERNAME", None)
         app.config.setdefault("LDAP_PASSWORD", None)
         app.config.setdefault("LDAP_TIMEOUT", 10)
@@ -68,9 +69,13 @@ class LDAP(object):
             ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
             ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, app.config["LDAP_CERT_PATH"])
 
-        for option in ["USERNAME", "PASSWORD", "BASE_DN"]:
-            if app.config["LDAP_{0}".format(option)] is None:
-                raise LDAPException("LDAP_{0} cannot be None!".format(option))
+        if app.config["LDAP_BASE_DN"] is None:
+            raise LDAPException("LDAP_BASE_DN cannot be None!")
+
+        if app.config["LDAP_SCHEMA"] != "ldapi":
+            for option in ["USERNAME", "PASSWORD"]:
+                if app.config["LDAP_{0}".format(option)] is None:
+                    raise LDAPException("LDAP_{0} cannot be None!".format(option))
 
     @staticmethod
     def _set_custom_options(conn):
@@ -88,13 +93,18 @@ class LDAP(object):
         """
 
         try:
-            conn = ldap.initialize(
-                "{0}://{1}:{2}".format(
+            if current_app.config["LDAP_SCHEMA"] == "ldapi":
+                uri = "{0}://{1}".format(
+                    current_app.config["LDAP_SCHEMA"],
+                    current_app.config["LDAP_SOCKET_PATH"],
+                )
+            else:
+                uri = "{0}://{1}:{2}".format(
                     current_app.config["LDAP_SCHEMA"],
                     current_app.config["LDAP_HOST"],
                     current_app.config["LDAP_PORT"],
                 )
-            )
+            conn = ldap.initialize(uri)
             conn.set_option(
                 ldap.OPT_NETWORK_TIMEOUT, current_app.config["LDAP_TIMEOUT"]
             )
-- 
GitLab