X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fipsilon.git;a=blobdiff_plain;f=ipsilon%2Flogin%2Fauthldap.py;h=1986490d7a2ee1169cf1ffdad42eef6ebbf4bd30;hp=321c461998cecc12cb55b1a3d2f95e0b7944325a;hb=f1efb10af288c438fa034e7beb62e14b8417056f;hpb=ea3a3c63719961c66b7b45cd7cfee51cf4bd5f6d diff --git a/ipsilon/login/authldap.py b/ipsilon/login/authldap.py index 321c461..1986490 100644 --- a/ipsilon/login/authldap.py +++ b/ipsilon/login/authldap.py @@ -8,6 +8,30 @@ from ipsilon.util import config as pconfig from ipsilon.info.infoldap import InfoProvider as LDAPInfo import ldap import subprocess +import logging + + +def ldap_connect(server_url, tls): + tls = tls.lower() + tls_req_opt = None + if tls == "never": + tls_req_opt = ldap.OPT_X_TLS_NEVER + elif tls == "demand": + tls_req_opt = ldap.OPT_X_TLS_DEMAND + elif tls == "allow": + tls_req_opt = ldap.OPT_X_TLS_ALLOW + elif tls == "try": + tls_req_opt = ldap.OPT_X_TLS_TRY + if tls_req_opt is not None: + ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, tls_req_opt) + + conn = ldap.initialize(server_url) + + if tls != "notls": + if not server_url.startswith("ldaps"): + conn.start_tls_s() + + return conn class LDAP(LoginFormBase, Log): @@ -17,26 +41,7 @@ class LDAP(LoginFormBase, Log): self.ldap_info = None def _ldap_connect(self): - - tls = self.lm.tls.lower() - tls_req_opt = None - if tls == "never": - tls_req_opt = ldap.OPT_X_TLS_NEVER - elif tls == "demand": - tls_req_opt = ldap.OPT_X_TLS_DEMAND - elif tls == "allow": - tls_req_opt = ldap.OPT_X_TLS_ALLOW - elif tls == "try": - tls_req_opt = ldap.OPT_X_TLS_TRY - if tls_req_opt is not None: - ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, tls_req_opt) - - conn = ldap.initialize(self.lm.server_url) - - if tls != "notls": - if not self.lm.server_url.startswith("ldaps"): - conn.start_tls_s() - return conn + return ldap_connect(self.lm.server_url, self.lm.tls) def _authenticate(self, username, password): @@ -200,7 +205,9 @@ class Installer(LoginManagerInstaller): help='LDAP Server Url') group.add_argument('--ldap-bind-dn-template', action='store', help='LDAP Bind DN Template') - group.add_argument('--ldap-tls-level', action='store', default=None, + group.add_argument('--ldap-tls-level', default='Demand', + choices=['Demand', 'Allow', 'Try', 'Never', + 'NoTLS'], help='LDAP TLS level') group.add_argument('--ldap-base-dn', action='store', help='LDAP Base DN') @@ -218,7 +225,17 @@ class Installer(LoginManagerInstaller): config = dict() if 'ldap_server_url' in opts: config['server url'] = opts['ldap_server_url'] + else: + logging.error('LDAP Server URL is required') + return False if 'ldap_bind_dn_template' in opts: + try: + opts['ldap_bind_dn_template'] % {'username': 'test'} + except KeyError: + logging.error( + 'Bind DN template does not container %(username)s' + ) + return False config['bind dn template'] = opts['ldap_bind_dn_template'] if 'ldap_tls_level' in opts and opts['ldap_tls_level'] is not None: config['tls'] = opts['ldap_tls_level'] @@ -226,6 +243,30 @@ class Installer(LoginManagerInstaller): config['tls'] = 'Demand' if 'ldap_base_dn' in opts and opts['ldap_base_dn'] is not None: config['base dn'] = opts['ldap_base_dn'] + test_dn = config['base dn'] + else: + # default set in the config object + test_dn = 'dc=example,dc=com' + + # Test the LDAP connection anonymously + try: + lh = ldap_connect(config['server url'], config['tls']) + lh.simple_bind_s('', '') + lh.search_s(test_dn, ldap.SCOPE_BASE, + attrlist=['objectclasses']) + except ldap.INSUFFICIENT_ACCESS: + logging.warn('Anonymous access not allowed, continuing') + except ldap.UNWILLING_TO_PERFORM: # probably minSSF issue + logging.warn('LDAP server unwilling to perform, expect issues') + except ldap.SERVER_DOWN: + logging.warn('LDAP server is down') + except ldap.NO_SUCH_OBJECT: + logging.error('Base DN not found') + return False + except ldap.LDAPError as e: + logging.error(e) + return False + po.save_plugin_config(config) # Update global config to add login plugin