Hello,

Attached patch adds a new ldap authentication configuration parameter
which indicates case sensitivity of the ldap schema/server.


Thanks,
Yogesh Mahajan
EnterpriseDB
diff --git a/docs/en_US/ldap.rst b/docs/en_US/ldap.rst
index 16cfb3fcf..371ba2394 100644
--- a/docs/en_US/ldap.rst
+++ b/docs/en_US/ldap.rst
@@ -73,17 +73,19 @@ There are 3 ways to configure LDAP:
    limits the search to the base object. A *level* search is restricted to the immediate
    children of a base object, but excludes the base object itself. A *subtree* search
    includes all child objects as well as the base object."
+   "LDAP_DN_CASE_SENSITIVE", "Indicates whether the DN (Distinguished Names) are case sensitive or not.
+   Possible values are True or False. By default is set to False."
    "LDAP_USE_STARTTLS","Specifies if you want to use Transport Layer Security (TLS)
    for secure communication between LDAP clients and LDAP servers. If you specify
    the connection protocol in *LDAP_SERVER_URI* as *ldaps*, this parameter is ignored."
    "LDAP_CA_CERT_FILE","Specifies the path to the trusted CA certificate file. This
-   parameter is applicable only if you are using *ldaps* as connection protocol and
+   parameter is applicable only if you are using *ldaps* as connection protocol or
    you have set *LDAP_USE_STARTTLS* parameter to *True*."
    "LDAP_CERT_FILE","Specifies the path to the server certificate file. This parameter
-   is applicable only if you are using *ldaps* as connection protocol and you have
+   is applicable only if you are using *ldaps* as connection protocol or you have
    set *LDAP_USE_STARTTLS* parameter to *True*."
    "LDAP_KEY_FILE","Specifies the path to the server private key file. This parameter
-   is applicable only if you are using *ldaps* as connection protocol and you have
+   is applicable only if you are using *ldaps* as connection protocol or you have
    set *LDAP_USE_STARTTLS* parameter to *True*."
    "**Bind as pgAdmin user**"
    "LDAP_BASE_DN","Specifies the base DN from where a server will start the search
diff --git a/web/config.py b/web/config.py
index f75f97130..af375e235 100644
--- a/web/config.py
+++ b/web/config.py
@@ -649,6 +649,10 @@ LDAP_BASE_DN = '<Base-DN>'
 # It can be optional while bind as pgAdmin user
 LDAP_SEARCH_BASE_DN = '<Search-Base-DN>'
 
+# The LDAP attribute indicates whether the DN (Distinguished Names)
+# are case sensitive or not
+LDAP_DN_CASE_SENSITIVE = False
+
 # Filter string for the user search.
 # For OpenLDAP, '(cn=*)' may well be enough.
 # For AD, you might use '(objectClass=user)' (REQUIRED)
diff --git a/web/pgadmin/authenticate/ldap.py b/web/pgadmin/authenticate/ldap.py
index c1d6fea65..2c022caef 100644
--- a/web/pgadmin/authenticate/ldap.py
+++ b/web/pgadmin/authenticate/ldap.py
@@ -24,7 +24,8 @@ from pgadmin.model import User, ServerGroup, db, Role
 from flask import current_app
 from pgadmin.tools.user_management import create_user
 from pgadmin.utils.constants import LDAP
-
+from sqlalchemy import func
+from flask_security import login_user
 
 ERROR_SEARCHING_LDAP_DIRECTORY = gettext(
     "Error searching the LDAP directory: {}")
@@ -133,7 +134,8 @@ class LDAPAuthentication(BaseAuthentication):
         except LDAPBindError as e:
             current_app.logger.exception(
                 "Error binding to the LDAP server.")
-            return False, gettext("Error binding to the LDAP server.")
+            return False, gettext("Error binding to the LDAP server: {}\n".
+                                  format(e.args[0]))
         except LDAPStartTLSError as e:
             current_app.logger.exception(
                 "Error starting TLS: {}\n".format(e))
@@ -146,11 +148,38 @@ class LDAPAuthentication(BaseAuthentication):
 
         return True, None
 
+    def login(self, form):
+        user = getattr(form, 'user', None)
+        if user is None:
+            if config.LDAP_DN_CASE_SENSITIVE:
+                user = User.query.filter_by(username=self.username).first()
+            else:
+                user = User.query.filter(
+                    func.lower(User.username) == func.lower(
+                        self.username)).first()
+
+        if user is None:
+            current_app.logger.exception(
+                self.messages('USER_DOES_NOT_EXIST'))
+            return False, self.messages('USER_DOES_NOT_EXIST')
+
+        # Login user through flask_security
+        status = login_user(user)
+        if not status:
+            current_app.logger.exception(self.messages('LOGIN_FAILED'))
+            return False, self.messages('LOGIN_FAILED')
+        return True, None
+
     def __auto_create_user(self, user_email):
         """Add the ldap user to the internal SQLite database."""
         if config.LDAP_AUTO_CREATE_USER:
-            user = User.query.filter_by(
-                username=self.username).first()
+            if config.LDAP_DN_CASE_SENSITIVE:
+                user = User.query.filter_by(username=self.username).first()
+            else:
+                user = User.query.filter(
+                    func.lower(User.username) == func.lower(
+                        self.username)).first()
+
             if user is None:
                 return create_user({
                     'username': self.username,

Reply via email to