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)
|
||||
|
||||
|
||||
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):
|
||||
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':
|
||||
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':
|
||||
IPAEntryLDAPObject.__init__(self,'ldap://%s' % format_netloc(self.host, self.port))
|
||||
ldap_uri = 'ldap://%s' % format_netloc(self.host, self.port)
|
||||
else:
|
||||
raise ValueError('Protocol %r not supported' % self.protocol)
|
||||
|
||||
LDAPConnection.__init__(self, ldap_uri)
|
||||
IPAEntryLDAPObject.__init__(self, ldap_uri)
|
||||
|
||||
def __guess_protocol(self):
|
||||
"""Return the protocol to use based on flags passed to the constructor
|
||||
|
||||
@ -913,51 +999,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
return sctrl
|
||||
|
||||
def __handle_errors(self, 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)
|
||||
return self.handle_errors(e, **kw)
|
||||
|
||||
def __wait_for_connection(self, timeout):
|
||||
lurl = ldapurl.LDAPUrl(self.uri)
|
||||
@ -1189,7 +1231,7 @@ class IPAdmin(IPAEntryLDAPObject):
|
||||
attrlist.append(attr)
|
||||
timeout += int(time.time())
|
||||
|
||||
if isinstance(dn,Entry):
|
||||
if isinstance(dn, LDAPEntry):
|
||||
dn = dn.dn
|
||||
assert isinstance(dn, DN)
|
||||
|
||||
|
@ -37,11 +37,10 @@ import krbV
|
||||
import ldap as _ldap
|
||||
import ldap.filter as _ldap_filter
|
||||
|
||||
from ipapython.ipa_log_manager import log_mgr
|
||||
from ipapython.dn import DN, RDN
|
||||
from ipalib.errors import NetworkError
|
||||
from ipaserver.ipaldap import (
|
||||
SASL_AUTH, unicode_from_utf8, value_to_utf8, IPASimpleLDAPObject)
|
||||
SASL_AUTH, unicode_from_utf8, value_to_utf8, IPASimpleLDAPObject,
|
||||
LDAPConnection)
|
||||
|
||||
|
||||
try:
|
||||
@ -70,7 +69,7 @@ MEMBERS_DIRECT = 1
|
||||
MEMBERS_INDIRECT = 2
|
||||
|
||||
|
||||
class ldap2(CrudBackend):
|
||||
class ldap2(LDAPConnection, CrudBackend):
|
||||
"""
|
||||
LDAP Backend Take 2.
|
||||
"""
|
||||
@ -90,12 +89,14 @@ class ldap2(CrudBackend):
|
||||
|
||||
def __init__(self, shared_instance=True, ldap_uri=None, base_dn=None,
|
||||
schema=None):
|
||||
CrudBackend.__init__(self, shared_instance=shared_instance)
|
||||
self.log = log_mgr.get_logger(self)
|
||||
try:
|
||||
self.ldap_uri = ldap_uri or api.env.ldap_uri
|
||||
ldap_uri = ldap_uri or api.env.ldap_uri
|
||||
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:
|
||||
if base_dn is not None:
|
||||
self.base_dn = DN(base_dn)
|
||||
@ -115,71 +116,6 @@ class ldap2(CrudBackend):
|
||||
return self.conn.schema
|
||||
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):
|
||||
if self.schema is None:
|
||||
return None
|
||||
|
Loading…
Reference in New Issue
Block a user