From 44134460b6545b51a17884ce353e556bd8cd753f Mon Sep 17 00:00:00 2001 From: Tomas Babej Date: Wed, 19 Nov 2014 12:00:07 +0100 Subject: [PATCH] baseldap: Handle missing parent objects properly in *-find commands The find_entries function in ipaldap does not differentiate between a LDAP search that returns error code 32 (No such object) and LDAP search returning error code 0 (Success), but returning no results. In both cases errors.NotFound is raised. In turn, LDAPSearch commands interpret NotFound exception as no results. To differentiate between the cases, a new error EmptyResult was added, which inherits from NotFound to preserve the compatibility with the new code. This error is raised by ipaldap.find_entries in case it is performing a search with and the target dn does not exist. https://fedorahosted.org/freeipa/ticket/4659 Reviewed-By: Jan Cholasta --- ipalib/errors.py | 15 +++++++++++++++ ipalib/plugins/baseldap.py | 4 +++- ipapython/ipaldap.py | 2 +- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/ipalib/errors.py b/ipalib/errors.py index f0426583d..89b1ef2e0 100644 --- a/ipalib/errors.py +++ b/ipalib/errors.py @@ -1329,6 +1329,21 @@ class PosixGroupViolation(ExecutionError): errno = 4030 format = _('This is already a posix group and cannot be converted to external one') +class EmptyResult(NotFound): + """ + **4031** Raised when a LDAP search returned no results. + + For example: + + >>> raise EmptyResult(reason='no matching entry found') + Traceback (most recent call last): + ... + EmptyResult: no matching entry found + + """ + + errno = 4031 + class BuiltinError(ExecutionError): """ **4100** Base class for builtin execution errors (*4100 - 4199*). diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py index 375441c0f..4b1c70192 100644 --- a/ipalib/plugins/baseldap.py +++ b/ipalib/plugins/baseldap.py @@ -1995,8 +1995,10 @@ class LDAPSearch(BaseLDAPCommand, crud.Search): time_limit=options.get('timelimit', None), size_limit=options.get('sizelimit', None) ) - except errors.NotFound: + except errors.EmptyResult: (entries, truncated) = ([], False) + except errors.NotFound: + self.api.Object[self.obj.parent_object].handle_not_found(*args[:-1]) for callback in self.get_callbacks('post'): truncated = callback(self, ldap, entries, truncated, *args, **options) diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py index 1702daa25..ce07006eb 100644 --- a/ipapython/ipaldap.py +++ b/ipapython/ipaldap.py @@ -1527,7 +1527,7 @@ class LDAPClient(object): break if not res and not truncated: - raise errors.NotFound(reason='no such entry') + raise errors.EmptyResult(reason='no matching entry found') return (res, truncated)