mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Start LDAPConnection, a common base for ldap2 and IPAdmin
The first method to be extracted is handle_errors Part of the work for: https://fedorahosted.org/freeipa/ticket/2660
This commit is contained in:
parent
9d41ee4b31
commit
df4ed77962
@ -816,18 +816,104 @@ class Entry(LDAPEntry):
|
|||||||
super(Entry, self).__init__(dn, data)
|
super(Entry, self).__init__(dn, data)
|
||||||
|
|
||||||
|
|
||||||
class IPAdmin(IPAEntryLDAPObject):
|
class LDAPConnection(object):
|
||||||
|
"""LDAP backend class
|
||||||
|
|
||||||
|
This class abstracts a LDAP connection, providing methods that work with
|
||||||
|
LADPEntries.
|
||||||
|
|
||||||
|
This class is not intended to be used directly; instead, use one of its
|
||||||
|
subclasses, IPAdmin or the ldap2 plugin.
|
||||||
|
"""
|
||||||
|
def __init__(self, ldap_uri):
|
||||||
|
self.ldap_uri = ldap_uri
|
||||||
|
self.log = log_mgr.get_logger(self)
|
||||||
|
|
||||||
|
def handle_errors(self, e, arg_desc=None):
|
||||||
|
"""Universal LDAPError handler
|
||||||
|
|
||||||
|
:param e: The error to be raised
|
||||||
|
:param url: The URL of the server
|
||||||
|
"""
|
||||||
|
if not isinstance(e, _ldap.TIMEOUT):
|
||||||
|
desc = e.args[0]['desc'].strip()
|
||||||
|
info = e.args[0].get('info', '').strip()
|
||||||
|
if arg_desc is not None:
|
||||||
|
info = "%s arguments: %s" % (info, arg_desc)
|
||||||
|
else:
|
||||||
|
desc = ''
|
||||||
|
info = ''
|
||||||
|
|
||||||
|
try:
|
||||||
|
# re-raise the error so we can handle it
|
||||||
|
raise e
|
||||||
|
except _ldap.NO_SUCH_OBJECT:
|
||||||
|
raise errors.NotFound(reason=arg_desc or 'no such entry')
|
||||||
|
except _ldap.ALREADY_EXISTS:
|
||||||
|
raise errors.DuplicateEntry()
|
||||||
|
except _ldap.CONSTRAINT_VIOLATION:
|
||||||
|
# This error gets thrown by the uniqueness plugin
|
||||||
|
_msg = 'Another entry with the same attribute value already exists'
|
||||||
|
if info.startswith(_msg):
|
||||||
|
raise errors.DuplicateEntry()
|
||||||
|
else:
|
||||||
|
raise errors.DatabaseError(desc=desc, info=info)
|
||||||
|
except _ldap.INSUFFICIENT_ACCESS:
|
||||||
|
raise errors.ACIError(info=info)
|
||||||
|
except _ldap.INVALID_CREDENTIALS:
|
||||||
|
raise errors.ACIError(info="%s %s" % (info, desc))
|
||||||
|
except _ldap.NO_SUCH_ATTRIBUTE:
|
||||||
|
# this is raised when a 'delete' attribute isn't found.
|
||||||
|
# it indicates the previous attribute was removed by another
|
||||||
|
# update, making the oldentry stale.
|
||||||
|
raise errors.MidairCollision()
|
||||||
|
except _ldap.INVALID_SYNTAX:
|
||||||
|
raise errors.InvalidSyntax(attr=info)
|
||||||
|
except _ldap.OBJECT_CLASS_VIOLATION:
|
||||||
|
raise errors.ObjectclassViolation(info=info)
|
||||||
|
except _ldap.ADMINLIMIT_EXCEEDED:
|
||||||
|
raise errors.LimitsExceeded()
|
||||||
|
except _ldap.SIZELIMIT_EXCEEDED:
|
||||||
|
raise errors.LimitsExceeded()
|
||||||
|
except _ldap.TIMELIMIT_EXCEEDED:
|
||||||
|
raise errors.LimitsExceeded()
|
||||||
|
except _ldap.NOT_ALLOWED_ON_RDN:
|
||||||
|
raise errors.NotAllowedOnRDN(attr=info)
|
||||||
|
except _ldap.FILTER_ERROR:
|
||||||
|
raise errors.BadSearchFilter(info=info)
|
||||||
|
except _ldap.NOT_ALLOWED_ON_NONLEAF:
|
||||||
|
raise errors.NotAllowedOnNonLeaf()
|
||||||
|
except _ldap.SERVER_DOWN:
|
||||||
|
raise errors.NetworkError(uri=self.ldap_uri,
|
||||||
|
error=u'LDAP Server Down')
|
||||||
|
except _ldap.LOCAL_ERROR:
|
||||||
|
raise errors.ACIError(info=info)
|
||||||
|
except _ldap.SUCCESS:
|
||||||
|
pass
|
||||||
|
except _ldap.LDAPError, e:
|
||||||
|
if 'NOT_ALLOWED_TO_DELEGATE' in info:
|
||||||
|
raise errors.ACIError(
|
||||||
|
info="KDC returned NOT_ALLOWED_TO_DELEGATE")
|
||||||
|
self.log.info('Unhandled LDAPError: %s' % str(e))
|
||||||
|
raise errors.DatabaseError(desc=desc, info=info)
|
||||||
|
|
||||||
|
|
||||||
|
class IPAdmin(LDAPConnection, IPAEntryLDAPObject):
|
||||||
|
|
||||||
def __localinit(self):
|
def __localinit(self):
|
||||||
if self.protocol == 'ldaps':
|
if self.protocol == 'ldaps':
|
||||||
IPAEntryLDAPObject.__init__(self,'ldaps://%s' % format_netloc(self.host, self.port))
|
ldap_uri = 'ldaps://%s' % format_netloc(self.host, self.port)
|
||||||
elif self.protocol == 'ldapi':
|
elif self.protocol == 'ldapi':
|
||||||
IPAEntryLDAPObject.__init__(self,'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % "-".join(self.realm.split(".")))
|
ldap_uri = 'ldapi://%%2fvar%%2frun%%2fslapd-%s.socket' % (
|
||||||
|
"-".join(self.realm.split(".")))
|
||||||
elif self.protocol == 'ldap':
|
elif self.protocol == 'ldap':
|
||||||
IPAEntryLDAPObject.__init__(self,'ldap://%s' % format_netloc(self.host, self.port))
|
ldap_uri = 'ldap://%s' % format_netloc(self.host, self.port)
|
||||||
else:
|
else:
|
||||||
raise ValueError('Protocol %r not supported' % self.protocol)
|
raise ValueError('Protocol %r not supported' % self.protocol)
|
||||||
|
|
||||||
|
LDAPConnection.__init__(self, ldap_uri)
|
||||||
|
IPAEntryLDAPObject.__init__(self, ldap_uri)
|
||||||
|
|
||||||
def __guess_protocol(self):
|
def __guess_protocol(self):
|
||||||
"""Return the protocol to use based on flags passed to the constructor
|
"""Return the protocol to use based on flags passed to the constructor
|
||||||
|
|
||||||
@ -913,51 +999,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
|||||||
return sctrl
|
return sctrl
|
||||||
|
|
||||||
def __handle_errors(self, e, **kw):
|
def __handle_errors(self, e, **kw):
|
||||||
"""
|
return self.handle_errors(e, **kw)
|
||||||
Centralize error handling in one place.
|
|
||||||
|
|
||||||
e is the error to be raised
|
|
||||||
**kw is an exception-specific list of options
|
|
||||||
"""
|
|
||||||
if not isinstance(e,ldap.TIMEOUT):
|
|
||||||
desc = e.args[0]['desc'].strip()
|
|
||||||
info = e.args[0].get('info','').strip()
|
|
||||||
arg_desc = kw.get('arg_desc')
|
|
||||||
if arg_desc is not None:
|
|
||||||
info += " arguments: %s" % arg_desc
|
|
||||||
else:
|
|
||||||
desc = ''
|
|
||||||
info = ''
|
|
||||||
|
|
||||||
try:
|
|
||||||
# re-raise the error so we can handle it
|
|
||||||
raise e
|
|
||||||
except ldap.NO_SUCH_OBJECT, e:
|
|
||||||
arg_desc = kw.get('arg_desc', "entry not found")
|
|
||||||
raise errors.NotFound(reason=arg_desc)
|
|
||||||
except ldap.ALREADY_EXISTS, e:
|
|
||||||
raise errors.DuplicateEntry()
|
|
||||||
except ldap.CONSTRAINT_VIOLATION, e:
|
|
||||||
# This error gets thrown by the uniqueness plugin
|
|
||||||
if info.startswith('Another entry with the same attribute value already exists'):
|
|
||||||
raise errors.DuplicateEntry()
|
|
||||||
else:
|
|
||||||
raise errors.DatabaseError(desc=desc,info=info)
|
|
||||||
except ldap.INSUFFICIENT_ACCESS, e:
|
|
||||||
raise errors.ACIError(info=info)
|
|
||||||
except ldap.NO_SUCH_ATTRIBUTE:
|
|
||||||
# this is raised when a 'delete' attribute isn't found.
|
|
||||||
# it indicates the previous attribute was removed by another
|
|
||||||
# update, making the oldentry stale.
|
|
||||||
raise errors.MidairCollision()
|
|
||||||
except ldap.ADMINLIMIT_EXCEEDED, e:
|
|
||||||
raise errors.LimitsExceeded()
|
|
||||||
except ldap.SIZELIMIT_EXCEEDED, e:
|
|
||||||
raise errors.LimitsExceeded()
|
|
||||||
except ldap.TIMELIMIT_EXCEEDED, e:
|
|
||||||
raise errors.LimitsExceeded()
|
|
||||||
except ldap.LDAPError, e:
|
|
||||||
raise errors.DatabaseError(desc=desc,info=info)
|
|
||||||
|
|
||||||
def __wait_for_connection(self, timeout):
|
def __wait_for_connection(self, timeout):
|
||||||
lurl = ldapurl.LDAPUrl(self.uri)
|
lurl = ldapurl.LDAPUrl(self.uri)
|
||||||
@ -1189,7 +1231,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
|||||||
attrlist.append(attr)
|
attrlist.append(attr)
|
||||||
timeout += int(time.time())
|
timeout += int(time.time())
|
||||||
|
|
||||||
if isinstance(dn,Entry):
|
if isinstance(dn, LDAPEntry):
|
||||||
dn = dn.dn
|
dn = dn.dn
|
||||||
assert isinstance(dn, DN)
|
assert isinstance(dn, DN)
|
||||||
|
|
||||||
|
@ -37,11 +37,10 @@ import krbV
|
|||||||
import ldap as _ldap
|
import ldap as _ldap
|
||||||
import ldap.filter as _ldap_filter
|
import ldap.filter as _ldap_filter
|
||||||
|
|
||||||
from ipapython.ipa_log_manager import log_mgr
|
|
||||||
from ipapython.dn import DN, RDN
|
from ipapython.dn import DN, RDN
|
||||||
from ipalib.errors import NetworkError
|
|
||||||
from ipaserver.ipaldap import (
|
from ipaserver.ipaldap import (
|
||||||
SASL_AUTH, unicode_from_utf8, value_to_utf8, IPASimpleLDAPObject)
|
SASL_AUTH, unicode_from_utf8, value_to_utf8, IPASimpleLDAPObject,
|
||||||
|
LDAPConnection)
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -70,7 +69,7 @@ MEMBERS_DIRECT = 1
|
|||||||
MEMBERS_INDIRECT = 2
|
MEMBERS_INDIRECT = 2
|
||||||
|
|
||||||
|
|
||||||
class ldap2(CrudBackend):
|
class ldap2(LDAPConnection, CrudBackend):
|
||||||
"""
|
"""
|
||||||
LDAP Backend Take 2.
|
LDAP Backend Take 2.
|
||||||
"""
|
"""
|
||||||
@ -90,12 +89,14 @@ class ldap2(CrudBackend):
|
|||||||
|
|
||||||
def __init__(self, shared_instance=True, ldap_uri=None, base_dn=None,
|
def __init__(self, shared_instance=True, ldap_uri=None, base_dn=None,
|
||||||
schema=None):
|
schema=None):
|
||||||
CrudBackend.__init__(self, shared_instance=shared_instance)
|
|
||||||
self.log = log_mgr.get_logger(self)
|
|
||||||
try:
|
try:
|
||||||
self.ldap_uri = ldap_uri or api.env.ldap_uri
|
ldap_uri = ldap_uri or api.env.ldap_uri
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
self.ldap_uri = 'ldap://example.com'
|
ldap_uri = 'ldap://example.com'
|
||||||
|
|
||||||
|
CrudBackend.__init__(self, shared_instance=shared_instance)
|
||||||
|
LDAPConnection.__init__(self, ldap_uri)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if base_dn is not None:
|
if base_dn is not None:
|
||||||
self.base_dn = DN(base_dn)
|
self.base_dn = DN(base_dn)
|
||||||
@ -115,71 +116,6 @@ class ldap2(CrudBackend):
|
|||||||
return self.conn.schema
|
return self.conn.schema
|
||||||
schema = property(_get_schema, None, None, 'schema associated with this LDAP server')
|
schema = property(_get_schema, None, None, 'schema associated with this LDAP server')
|
||||||
|
|
||||||
# universal LDAPError handler
|
|
||||||
def handle_errors(self, e):
|
|
||||||
"""
|
|
||||||
Centralize error handling in one place.
|
|
||||||
|
|
||||||
e is the error to be raised
|
|
||||||
"""
|
|
||||||
if not isinstance(e, _ldap.TIMEOUT):
|
|
||||||
desc = e.args[0]['desc'].strip()
|
|
||||||
info = e.args[0].get('info', '').strip()
|
|
||||||
else:
|
|
||||||
desc = ''
|
|
||||||
info = ''
|
|
||||||
|
|
||||||
try:
|
|
||||||
# re-raise the error so we can handle it
|
|
||||||
raise e
|
|
||||||
except _ldap.NO_SUCH_OBJECT:
|
|
||||||
raise errors.NotFound(reason='no such entry')
|
|
||||||
except _ldap.ALREADY_EXISTS:
|
|
||||||
raise errors.DuplicateEntry()
|
|
||||||
except _ldap.CONSTRAINT_VIOLATION:
|
|
||||||
# This error gets thrown by the uniqueness plugin
|
|
||||||
if info.startswith('Another entry with the same attribute value already exists'):
|
|
||||||
raise errors.DuplicateEntry()
|
|
||||||
else:
|
|
||||||
raise errors.DatabaseError(desc=desc, info=info)
|
|
||||||
except _ldap.INSUFFICIENT_ACCESS:
|
|
||||||
raise errors.ACIError(info=info)
|
|
||||||
except _ldap.INVALID_CREDENTIALS:
|
|
||||||
raise errors.ACIError(info="%s %s" % (info, desc))
|
|
||||||
except _ldap.NO_SUCH_ATTRIBUTE:
|
|
||||||
# this is raised when a 'delete' attribute isn't found.
|
|
||||||
# it indicates the previous attribute was removed by another
|
|
||||||
# update, making the oldentry stale.
|
|
||||||
raise errors.MidairCollision()
|
|
||||||
except _ldap.INVALID_SYNTAX:
|
|
||||||
raise errors.InvalidSyntax(attr=info)
|
|
||||||
except _ldap.OBJECT_CLASS_VIOLATION:
|
|
||||||
raise errors.ObjectclassViolation(info=info)
|
|
||||||
except _ldap.ADMINLIMIT_EXCEEDED:
|
|
||||||
raise errors.LimitsExceeded()
|
|
||||||
except _ldap.SIZELIMIT_EXCEEDED:
|
|
||||||
raise errors.LimitsExceeded()
|
|
||||||
except _ldap.TIMELIMIT_EXCEEDED:
|
|
||||||
raise errors.LimitsExceeded()
|
|
||||||
except _ldap.NOT_ALLOWED_ON_RDN:
|
|
||||||
raise errors.NotAllowedOnRDN(attr=info)
|
|
||||||
except _ldap.FILTER_ERROR:
|
|
||||||
raise errors.BadSearchFilter(info=info)
|
|
||||||
except _ldap.NOT_ALLOWED_ON_NONLEAF:
|
|
||||||
raise errors.NotAllowedOnNonLeaf()
|
|
||||||
except _ldap.SERVER_DOWN:
|
|
||||||
raise NetworkError(uri=self.ldap_uri,
|
|
||||||
error=u'LDAP Server Down')
|
|
||||||
except _ldap.LOCAL_ERROR:
|
|
||||||
raise errors.ACIError(info=info)
|
|
||||||
except _ldap.SUCCESS:
|
|
||||||
pass
|
|
||||||
except _ldap.LDAPError, e:
|
|
||||||
if 'NOT_ALLOWED_TO_DELEGATE' in info:
|
|
||||||
raise errors.ACIError(info="KDC returned NOT_ALLOWED_TO_DELEGATE")
|
|
||||||
self.info('Unhandled LDAPError: %s' % str(e))
|
|
||||||
raise errors.DatabaseError(desc=desc, info=info)
|
|
||||||
|
|
||||||
def get_syntax(self, attr, value):
|
def get_syntax(self, attr, value):
|
||||||
if self.schema is None:
|
if self.schema is None:
|
||||||
return None
|
return None
|
||||||
|
Loading…
Reference in New Issue
Block a user