[checkmk-commits] Check_MK Git: check_mk: ldap connection: Better error handling, replacing OMD_SITE in distinguished names from config now

git version control git at mathias-kettner.de
Wed Nov 21 14:35:05 CET 2012


Module: check_mk
Branch: master
Commit: 393b8a0e013c8322a09140a152ce3f86f0e69f29
URL:    http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=393b8a0e013c8322a09140a152ce3f86f0e69f29

Author: Lars Michelsen <lm at mathias-kettner.de>
Date:   Tue Nov 13 14:38:30 2012 +0100

ldap connection: Better error handling, replacing OMD_SITE in distinguished names from config now

---

 web/htdocs/valuespec.py                    |   25 +++++++++++++++
 web/plugins/userdb/ldap.py                 |   46 ++++++++++++++++++++++------
 web/plugins/wato/check_mk_configuration.py |    8 ++--
 3 files changed, 65 insertions(+), 14 deletions(-)

diff --git a/web/htdocs/valuespec.py b/web/htdocs/valuespec.py
index 1e6ea41..6d43212 100644
--- a/web/htdocs/valuespec.py
+++ b/web/htdocs/valuespec.py
@@ -2112,3 +2112,28 @@ class Transform(ValueSpec):
 
     def validate_value(self, value, varprefix):
         self._valuespec.validate_value(self.forth(value), varprefix)
+
+class LDAPDistinguishedName(TextAscii):
+    def __init__(self, **kwargs):
+        TextAscii.__init__(self, **kwargs)
+
+    def validate_value(self, value, varprefix):
+        TextAscii.validate_value(self, value, varprefix)
+
+        if value:
+            import ldap
+            try:
+                dn = ldap.dn.str2dn(value)
+            except ldap.DECODING_ERROR:
+                raise MKUserError(varprefix, _('Unable to parse the given distingushed name.'))
+
+            # At least one DC= must be in distinguished name
+            found_dc = False
+            for part in dn:
+                html.write(repr(part[0]))
+                key, val = part[0][:2]
+                if key.lower() == 'dc':
+                    found_dc = True
+
+            if not found_dc:
+                raise MKUserError(varprefix, _('Found no "dc=" (Domain Component).'))
diff --git a/web/plugins/userdb/ldap.py b/web/plugins/userdb/ldap.py
index 9e40175..def1134 100644
--- a/web/plugins/userdb/ldap.py
+++ b/web/plugins/userdb/ldap.py
@@ -24,7 +24,7 @@
 # to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
 # Boston, MA 02110-1301 USA.
 
-import config
+import config, defaults
 
 # FIXME: For some reason mod_python is missing /usr/lib/python2.7/dist-packages
 # in sys.path. Therefor the ldap module can not be found. Need to fix this!
@@ -102,21 +102,35 @@ def ldap_connect():
         ldap_default_bind()
 
     except ldap.LDAPError, e:
+        ldap_connection = None # Invalidate connection on failure
         raise MKLDAPException(e)
 
+    except Exception:
+        ldap_connection = None # Invalidate connection on failure
+        raise
+
 # Bind with the default credentials
 def ldap_default_bind():
-    if config.ldap_connection['bind']:
-        ldap_bind(config.ldap_connection['bind'][0],
-                  config.ldap_connection['bind'][1])
-    else:
-        ldap_bind('', '') # anonymous bind
+    try:
+        if config.ldap_connection['bind']:
+            ldap_bind(ldap_dn(config.ldap_connection['bind'][0]),
+                      config.ldap_connection['bind'][1], catch = False)
+        else:
+            ldap_bind('', '', catch = False) # anonymous bind
+    except (ldap.INVALID_CREDENTIALS, ldap.INAPPROPRIATE_AUTH):
+        raise MKLDAPException(_('Unable to connect to LDAP server with the configured bind credentials. '
+                                'Plase fix this in the '
+                                '<a href="wato.py?mode=edit_configvar&varname=ldap_connection">LDAP '
+                                'connection settings</a>.'))
 
-def ldap_bind(username, password):
+def ldap_bind(username, password, catch = True):
     try:
         ldap_connection.simple_bind_s(username, password)
     except ldap.LDAPError, e:
-        raise MKLDAPException(_('Unable to authenticate with LDAP (%s)' % e))
+        if catch:
+            raise MKLDAPException(_('Unable to authenticate with LDAP (%s)' % e))
+        else:
+            raise
 
 def ldap_search(base, filt = '(objectclass=*)', columns = [], scope = None):
     if scope:
@@ -151,12 +165,24 @@ def ldap_attr(key):
 def ldap_attrs(keys):
     return map(ldap_attr, keys)
 
+# Returns the given distinguished name template with replaced vars
+def ldap_dn(tmpl):
+    dn = tmpl
+
+    for key, val in [ ('$OMD_SITE$', defaults.omd_site) ]:
+        if val:
+            dn = dn.replace(key, val)
+        else:
+            dn = dn.replace(key, '')
+
+    return dn
+
 def get_user_dn(username):
     # Check wether or not the user exists in the directory
     # It's only ok when exactly one entry is found.
     # Returns the DN in this case.
     result = ldap_search(
-        config.ldap_userspec['user_dn'],
+        ldap_dn(config.ldap_userspec['user_dn']),
         '(%s=%s)' % (ldap_attr('user_id'), ldap.filter.escape_filter_chars(username)),
         [key],
     )
@@ -174,7 +200,7 @@ def ldap_get_users(add_filter = None):
         filt = '(&%s%s)' % (filt, add_filter)
 
     result = {}
-    for dn, ldap_user in ldap_search(config.ldap_userspec['user_dn'], filt, columns = columns):
+    for dn, ldap_user in ldap_search(ldap_dn(config.ldap_userspec['user_dn']), filt, columns = columns):
         user_id = ldap_user[ldap_attr('user_id')][0]
         result[user_id] = ldap_user
 
diff --git a/web/plugins/wato/check_mk_configuration.py b/web/plugins/wato/check_mk_configuration.py
index f6c2c78..0ed6f4a 100644
--- a/web/plugins/wato/check_mk_configuration.py
+++ b/web/plugins/wato/check_mk_configuration.py
@@ -337,7 +337,7 @@ if userdb.connector_enabled('ldap'):
                 ("bind", Optional(
                     Tuple(
                         elements = [
-                            TextAscii(
+                            LDAPDistinguishedName(
                                 title = _("Bind DN"),
                                 help  = _("Specify the distinguished name to be used to bind to "
                                           "the LDAP directory."),
@@ -365,7 +365,7 @@ if userdb.connector_enabled('ldap'):
         ),
         domain = "multisite",
     )
-    
+
     register_configvar(group,
         "ldap_userspec",
         Dictionary(
@@ -373,13 +373,13 @@ if userdb.connector_enabled('ldap'):
             help  = _("This option configures all user related LDAP options. These options "
                       "are used by the LDAP user connector to find the needed users in the LDAP directory."),
             elements = [
-                ("user_dn", TextAscii(
+                ("user_dn", LDAPDistinguishedName(
                     title = _("User Base DN"),
                     help  = _("The base distinguished name to be used when performing user account "
                               "related queries to the LDAP server."),
                     size = 80,
                 )),
-                ("group_dn", TextAscii(
+                ("group_dn", LDAPDistinguishedName(
                     title = _("Group Base DN"),
                     help  = _("The base distinguished name to be used when performing group "
                               "related queries to the LDAP server."),



More information about the checkmk-commits mailing list