Forked from
DM / dm-docs
261 commits behind, 816 commits ahead of the upstream repository.
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
ldapClient.py 3.58 KiB
#!/usr/bin/env python
import ldap
import re
from dm.common.utility.loggingManager import LoggingManager
from dm.common.exceptions.configurationError import ConfigurationError
from dm.common.exceptions.internalError import InternalError
from dm.common.exceptions.objectNotFound import ObjectNotFound
from dm.common.exceptions.authenticationError import AuthenticationError
from dm.common.exceptions.communicationError import CommunicationError
from dm.common.exceptions.dmException import DmException
class LdapClient:
LDAP_ERROR_REGEX_LIST = [
(re.compile('.*No such object.*'),ObjectNotFound),
(re.compile('.*'),DmException)
]
def __init__(self, serverUrl, adminDn, adminPasswordFile):
self.serverUrl = serverUrl
self.adminDn = adminDn
self.adminPassword = open(adminPasswordFile, 'r').readline().strip()
if not self.adminPassword:
raise ConfigurationError('LDAP password could not be found in %s file' % adminPasswordFile)
self.ldapClient = None
# Decorator for all LDAP transactions
@classmethod
def executeLdapCall(cls, func):
def ldapCall(*args, **kwargs):
try:
result = func(*args, **kwargs)
return result
except ldap.NO_SUCH_OBJECT, ex:
raise ObjectNotFound(str(ex))
except DmException, ex:
raise
except Exception, ex:
error = str(ex)
for (pattern,dmExClass) in LdapClient.LDAP_ERROR_REGEX_LIST:
if pattern.match(error):
raise dmExClass(exception=ex)
raise DmException(exception=ex)
return ldapCall
@classmethod
def getLogger(cls):
logger = LoggingManager.getInstance().getLogger(cls.__name__)
return logger
def getLdapClient(self):
if self.ldapClient is not None:
try:
self.ldapClient.simple_bind_s(self.adminDn, self.adminPassword)
except Exception, ex:
self.getLogger().error('Invalidating LDAP client due to error: %s' % ex)
self.unbind(self.ldapClient)
self.ldapClient = None
if not self.ldapClient:
self.ldapClient = self.bind(self.serverUrl, self.adminDn, self.adminPassword)
return self.ldapClient
@classmethod
def bind(cls, serverUrl, adminDn, adminPassword):
try:
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
ldapClient = ldap.initialize(serverUrl)
ldapClient.set_option(ldap.OPT_REFERRALS,0)
ldapClient.set_option(ldap.OPT_PROTOCOL_VERSION, ldap.VERSION3)
ldapClient.simple_bind_s(adminDn, adminPassword)
cls.getLogger().debug('Successful binding with LDAP DN: %s' % adminDn)
return ldapClient
except ldap.INVALID_CREDENTIALS, ex:
ldapClient.unbind()
raise AuthenticationError('Invalid LDAP credentials for admin user %s' % adminDn)
except ldap.SERVER_DOWN, ex:
raise CommunicationError('Cannot reach LDAP server %s' % serverUrl)
except Exception, ex:
raise InternalError('Unrecognized exception while binding to LDAP server %s: %s' % (serverUrl, ex))
@classmethod
def unbind(cls, ldapClient):
try:
ldapClient.unbind()
except Exception, ex:
cls.getLogger().error('Could not unbind LDAP client: %s' % ex)
#######################################################################
# Testing.
if __name__ == '__main__':
pass