Module: check_mk
Branch: master
Commit: 393b8a0e013c8322a09140a152ce3f86f0e69f29
URL: http://git.mathias-kettner.de/git/?p=check_mk.git;a=commit;h=393b8a0e013c83…
Author: Lars Michelsen <lm(a)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."),