forked from shaba/openuds
Updating windowmain to be functional on python2 & python3
This commit is contained in:
parent
54136ae077
commit
ca0fc6a61d
@ -43,6 +43,18 @@ from uds.core.util import tools
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class LDAPError(Exception):
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def reraise(e):
|
||||||
|
_str = _('Connection error: ')
|
||||||
|
if hasattr(e, 'message') and isinstance(e.message, dict):
|
||||||
|
_str += ', '.join((e.message.get('info', ''), e.message.get('desc')))
|
||||||
|
else:
|
||||||
|
_str += "{}".format(e)
|
||||||
|
raise LDAPError(_str)
|
||||||
|
|
||||||
|
|
||||||
def escape(value):
|
def escape(value):
|
||||||
"""
|
"""
|
||||||
Escape filter chars for ldap search filter
|
Escape filter chars for ldap search filter
|
||||||
@ -78,17 +90,12 @@ def connection(username, password, host, port=-1, ssl=False, timeout=3, debug=Fa
|
|||||||
|
|
||||||
l.simple_bind_s(who=username, cred=password)
|
l.simple_bind_s(who=username, cred=password)
|
||||||
except ldap.SERVER_DOWN:
|
except ldap.SERVER_DOWN:
|
||||||
raise Exception(_('Can\'t contact LDAP server'))
|
raise LDAPError(_('Can\'t contact LDAP server'))
|
||||||
except ldap.LDAPError as e:
|
except ldap.LDAPError as e:
|
||||||
_str = _('Connection error: ')
|
LDAPError.reraise(e)
|
||||||
if hasattr(e, 'message') and isinstance(e.message, dict):
|
except Exception as e:
|
||||||
_str += ', '.join((e.message.get('info', ''), e.message.get('desc')))
|
|
||||||
else:
|
|
||||||
_str += "{}".format(e)
|
|
||||||
raise Exception(_str)
|
|
||||||
except Exception:
|
|
||||||
logger.exception('Exception connection:')
|
logger.exception('Exception connection:')
|
||||||
raise
|
raise LDAPError('{}'.format(e))
|
||||||
|
|
||||||
logger.debug('Conneciton was success')
|
logger.debug('Conneciton was success')
|
||||||
return l
|
return l
|
||||||
@ -104,13 +111,19 @@ def getAsDict(con, base, ldapFilter, attrList, sizeLimit, scope=ldap.SCOPE_SUBTR
|
|||||||
if attrList is not None:
|
if attrList is not None:
|
||||||
attrList = [tools.b2(i) for i in attrList]
|
attrList = [tools.b2(i) for i in attrList]
|
||||||
|
|
||||||
# On python2, attrs and search string is str (not unicode), in 3, str (not bytes)
|
try:
|
||||||
res = con.search_ext_s(base,
|
# On python2, attrs and search string is str (not unicode), in 3, str (not bytes)
|
||||||
scope=scope,
|
res = con.search_ext_s(base,
|
||||||
filterstr=tools.b2(ldapFilter),
|
scope=scope,
|
||||||
attrlist=attrList,
|
filterstr=tools.b2(ldapFilter),
|
||||||
sizelimit=sizeLimit
|
attrlist=attrList,
|
||||||
)
|
sizelimit=sizeLimit
|
||||||
|
)
|
||||||
|
except ldap.LDAPError as e:
|
||||||
|
LDAPError.reraise(e)
|
||||||
|
except Exception as e:
|
||||||
|
logger.exception('Exception connection:')
|
||||||
|
raise LDAPError('{}'.format(e))
|
||||||
|
|
||||||
logger.debug('Result of search {} on {}: {}'.format(ldapFilter, base, res))
|
logger.debug('Result of search {} on {}: {}'.format(ldapFilter, base, res))
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ from uds.core.managers.CryptoManager import CryptoManager
|
|||||||
from uds.core import osmanagers
|
from uds.core import osmanagers
|
||||||
from uds.core.util import log
|
from uds.core.util import log
|
||||||
from uds.core.util import encoders
|
from uds.core.util import encoders
|
||||||
|
from uds.core.util import ldaputil
|
||||||
|
|
||||||
import dns.resolver
|
import dns.resolver
|
||||||
import ldap
|
import ldap
|
||||||
from .WindowsOsManager import WindowsOsManager
|
from .WindowsOsManager import WindowsOsManager
|
||||||
@ -76,16 +78,6 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
if self._ou.lower().find(lpath) == -1:
|
if self._ou.lower().find(lpath) == -1:
|
||||||
self._ou += ',' + lpath
|
self._ou += ',' + lpath
|
||||||
|
|
||||||
def __getLdapError(self, e):
|
|
||||||
logger.debug('Ldap Error: {0} {1}'.format(e, e.message))
|
|
||||||
_str = ''
|
|
||||||
if type(e.message) == dict:
|
|
||||||
# _str += e.message.has_key('info') and e.message['info'] + ',' or ''
|
|
||||||
_str += e.message.get('desc', '')
|
|
||||||
else:
|
|
||||||
_str += str(e)
|
|
||||||
return _str
|
|
||||||
|
|
||||||
def __getServerList(self):
|
def __getServerList(self):
|
||||||
if self._serverHint != '':
|
if self._serverHint != '':
|
||||||
yield (self._serverHint, 389)
|
yield (self._serverHint, 389)
|
||||||
@ -98,61 +90,54 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
Tries to connect to LDAP
|
Tries to connect to LDAP
|
||||||
Raises an exception if not found:
|
Raises an exception if not found:
|
||||||
dns.resolver.NXDOMAIN
|
dns.resolver.NXDOMAIN
|
||||||
ldap.LDAPError
|
ldaputil.LDAPError
|
||||||
"""
|
"""
|
||||||
if servers is None:
|
if servers is None:
|
||||||
servers = self.__getServerList()
|
servers = self.__getServerList()
|
||||||
|
|
||||||
|
account = self._account
|
||||||
|
if account.find('@') == -1:
|
||||||
|
account += '@' + self._domain
|
||||||
|
|
||||||
_str = "No servers found"
|
_str = "No servers found"
|
||||||
for server in servers:
|
for server in servers:
|
||||||
_str = ''
|
_str = ''
|
||||||
|
|
||||||
try:
|
try:
|
||||||
uri = "%s://%s:%d" % ('ldap', server[0], server[1])
|
return ldaputil.connection(account, self._password, server[0], server[1], ssl=False, timeout=10, debug=False)
|
||||||
logger.debug('URI: {0}'.format(uri))
|
except Exception as e:
|
||||||
|
_str = 'Error: {}'.format(e)
|
||||||
|
|
||||||
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER) # Disable certificate check
|
raise ldaputil.LDAPError(_str)
|
||||||
l = ldap.initialize(uri=uri)
|
|
||||||
l.set_option(ldap.OPT_REFERRALS, 0)
|
|
||||||
l.network_timeout = l.timeout = 5
|
|
||||||
l.protocol_version = ldap.VERSION3
|
|
||||||
|
|
||||||
account = self._account
|
|
||||||
if account.find('@') == -1:
|
|
||||||
account += '@' + self._domain
|
|
||||||
|
|
||||||
logger.debug('Account data: {0}, {1}, {2}, {3}'.format(self._account, self._domain, account, self._password))
|
|
||||||
|
|
||||||
l.simple_bind_s(who=account, cred=self._password)
|
|
||||||
|
|
||||||
return l
|
|
||||||
except ldap.LDAPError as e:
|
|
||||||
_str = self.__getLdapError(e)
|
|
||||||
|
|
||||||
raise ldap.LDAPError(_str)
|
|
||||||
|
|
||||||
def __getGroup(self, l):
|
def __getGroup(self, l):
|
||||||
base = ','.join(['DC=' + i for i in self._domain.split('.')])
|
base = ','.join(['DC=' + i for i in self._domain.split('.')])
|
||||||
group = self._group.replace('\\', '\\\\').replace('(', '\\(').replace(')', '\\)')
|
group = ldaputil.escape(self._group)
|
||||||
|
try:
|
||||||
|
obj = next(ldaputil.getAsDict(l, base, "(&(objectClass=group)(|(cn={0})(sAMAccountName={0})))".format(group), ['dn'], sizeLimit=50))
|
||||||
|
except StopIteration:
|
||||||
|
obj = None
|
||||||
|
|
||||||
res = l.search_ext_s(base=base, scope=ldap.SCOPE_SUBTREE, filterstr="(&(objectClass=group)(|(cn={0})(sAMAccountName={0})))".format(group), attrlist=[b'dn'])
|
if obj is None:
|
||||||
if res[0] is None:
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return res[0][0] # Returns the DN
|
return obj['dn'] # Returns the DN
|
||||||
|
|
||||||
def __getMachine(self, l, machineName):
|
def __getMachine(self, l, machineName):
|
||||||
if self._ou:
|
if self._ou:
|
||||||
ou = self._ou
|
base = self._ou
|
||||||
else:
|
else:
|
||||||
ou = ','.join(['DC=' + i for i in self._domain.split('.')])
|
base = ','.join(['DC=' + i for i in self._domain.split('.')])
|
||||||
|
|
||||||
fltr = '(&(objectClass=computer)(sAMAccountName={}$))'.format(machineName)
|
fltr = '(&(objectClass=computer)(sAMAccountName={}$))'.format(ldaputil.escape(machineName))
|
||||||
res = l.search_ext_s(base=ou, scope=ldap.SCOPE_SUBTREE, filterstr=fltr, attrlist=[b'dn'])
|
try:
|
||||||
if res[0] is None:
|
obj = next(ldaputil.getAsDict(l, base, fltr, ['dn'], sizeLimit=50))
|
||||||
|
except StopIteration:
|
||||||
|
obj = None
|
||||||
|
|
||||||
|
if obj is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
return res[0][0] # Returns the DN
|
return obj['dn'] # Returns the DN
|
||||||
|
|
||||||
def readyReceived(self, userService, data):
|
def readyReceived(self, userService, data):
|
||||||
# No group to add
|
# No group to add
|
||||||
@ -173,6 +158,9 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
|
|
||||||
machine = self.__getMachine(l, userService.friendly_name)
|
machine = self.__getMachine(l, userService.friendly_name)
|
||||||
group = self.__getGroup(l)
|
group = self.__getGroup(l)
|
||||||
|
# #
|
||||||
|
# Direct LDAP operation "modify", maybe this need to be added to ldaputil? :)
|
||||||
|
# #
|
||||||
l.modify_s(group, ((ldap.MOD_ADD, 'member', machine),))
|
l.modify_s(group, ((ldap.MOD_ADD, 'member', machine),))
|
||||||
error = None
|
error = None
|
||||||
break
|
break
|
||||||
@ -183,7 +171,7 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
# Already added this machine to this group, pass
|
# Already added this machine to this group, pass
|
||||||
error = None
|
error = None
|
||||||
break
|
break
|
||||||
except ldap.LDAPError:
|
except ldaputil.LDAPError:
|
||||||
logger.exception('Ldap Exception caught')
|
logger.exception('Ldap Exception caught')
|
||||||
error = "Could not remove machine from domain (invalid credentials for {0})".format(self._account)
|
error = "Could not remove machine from domain (invalid credentials for {0})".format(self._account)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -210,7 +198,7 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
logger.warn('Could not find _ldap._tcp.' + self._domain)
|
logger.warn('Could not find _ldap._tcp.' + self._domain)
|
||||||
log.doLog(service, log.WARN, "Could not remove machine from domain (_ldap._tcp.{0} not found)".format(self._domain), log.OSMANAGER)
|
log.doLog(service, log.WARN, "Could not remove machine from domain (_ldap._tcp.{0} not found)".format(self._domain), log.OSMANAGER)
|
||||||
return
|
return
|
||||||
except ldap.LDAPError:
|
except ldaputil.LDAPError:
|
||||||
logger.exception('Ldap Exception caught')
|
logger.exception('Ldap Exception caught')
|
||||||
log.doLog(service, log.WARN, "Could not remove machine from domain (invalid credentials for {0})".format(self._account), log.OSMANAGER)
|
log.doLog(service, log.WARN, "Could not remove machine from domain (invalid credentials for {0})".format(self._account), log.OSMANAGER)
|
||||||
return
|
return
|
||||||
@ -222,6 +210,9 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
res = self.__getMachine(l, service.friendly_name)
|
res = self.__getMachine(l, service.friendly_name)
|
||||||
if res is None:
|
if res is None:
|
||||||
raise Exception('Machine {} not found on AD (permissions?)'.format(service.friendly_name))
|
raise Exception('Machine {} not found on AD (permissions?)'.format(service.friendly_name))
|
||||||
|
# #
|
||||||
|
# Direct LDAP operation "modify", maybe this need to be added to ldaputil? :)
|
||||||
|
# #
|
||||||
l.delete_s(res) # Remove by DN, SYNC
|
l.delete_s(res) # Remove by DN, SYNC
|
||||||
except IndexError:
|
except IndexError:
|
||||||
logger.error('Error deleting {} from BASE {}'.format(service.friendly_name, self._ou))
|
logger.error('Error deleting {} from BASE {}'.format(service.friendly_name, self._ou))
|
||||||
@ -231,7 +222,7 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
def check(self):
|
def check(self):
|
||||||
try:
|
try:
|
||||||
l = self.__connectLdap()
|
l = self.__connectLdap()
|
||||||
except ldap.LDAPError as e:
|
except ldaputil.LDAPError as e:
|
||||||
return _('Check error: {0}').format(self.__getLdapError(e))
|
return _('Check error: {0}').format(self.__getLdapError(e))
|
||||||
except dns.resolver.NXDOMAIN:
|
except dns.resolver.NXDOMAIN:
|
||||||
return [True, _('Could not find server parameters (_ldap._tcp.{0} can\'t be resolved)').format(self._domain)]
|
return [True, _('Could not find server parameters (_ldap._tcp.{0} can\'t be resolved)').format(self._domain)]
|
||||||
@ -241,7 +232,7 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
l.search_st(self._ou, ldap.SCOPE_BASE)
|
l.search_st(self._ou, ldap.SCOPE_BASE)
|
||||||
except ldap.LDAPError as e:
|
except ldaputil.LDAPError as e:
|
||||||
return _('Check error: {0}').format(self.__getLdapError(e))
|
return _('Check error: {0}').format(self.__getLdapError(e))
|
||||||
|
|
||||||
# Group
|
# Group
|
||||||
@ -260,7 +251,7 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
logger.debug(wd)
|
logger.debug(wd)
|
||||||
try:
|
try:
|
||||||
l = wd.__connectLdap()
|
l = wd.__connectLdap()
|
||||||
except ldap.LDAPError as e:
|
except ldaputil.LDAPError as e:
|
||||||
return [False, _('Could not access AD using LDAP ({0})').format(wd.__getLdapError(e))]
|
return [False, _('Could not access AD using LDAP ({0})').format(wd.__getLdapError(e))]
|
||||||
|
|
||||||
ou = wd._ou
|
ou = wd._ou
|
||||||
@ -271,7 +262,7 @@ class WinDomainOsManager(WindowsOsManager):
|
|||||||
r = l.search_st(ou, ldap.SCOPE_BASE)
|
r = l.search_st(ou, ldap.SCOPE_BASE)
|
||||||
logger.debug('Result of search: {0}'.format(r))
|
logger.debug('Result of search: {0}'.format(r))
|
||||||
|
|
||||||
except ldap.LDAPError:
|
except ldaputil.LDAPError:
|
||||||
if wd._ou == '':
|
if wd._ou == '':
|
||||||
return [False, _('The default path {0} for computers was not found!!!').format(wd._ou)]
|
return [False, _('The default path {0} for computers was not found!!!').format(wd._ou)]
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user