def _search(self, search_filter=None, retrieve_attributes=None, base=None, scope=libldap.LDAP_SCOPE_SUBTREE, retrieve_operational_attributes=False): """Search without retry_reconnect.""" try: raw_search_result = self._raw_search(search_filter=search_filter, retrieve_attributes=retrieve_attributes, base=base,scope=scope, retrieve_operational_attributes=retrieve_operational_attributes) for dn, attributes_dict in raw_search_result: entry = LDAPEntry(self, compat._decode_utf8(dn), retrieve_attributes=retrieve_attributes, retrieve_operational_attributes=retrieve_operational_attributes) entry._attributes = set() for name, value in attributes_dict.items(): # TODO: Create the right type of LDAPAttribute here attribute_type = self.get_attribute_type( compat._decode_utf8(name)) attribute = attribute_type(compat._decode_utf8(name)) attribute._set_ldap_values(value) entry._attributes.add(attribute) entry._fetched_attributes = copy.deepcopy(entry._attributes) yield entry except error.LDAPNoSuchObjectError: # If the search returned without results, "return" an empty generator. return
def _search(self, *args, **kwargs): """Search without retry_reconnect.""" try: for dn, attributes_dict in self._raw_search(*args, **kwargs): entry = LDAPEntry(self, compat._decode_utf8(dn)) entry._attributes = set() for name, value in attributes_dict.items(): # TODO: Create the right type of LDAPAttribute here attribute_type = self.get_attribute_type( compat._decode_utf8(name)) attribute = attribute_type(compat._decode_utf8(name)) attribute._set_ldap_values(value) entry._attributes.add(attribute) entry._fetched_attributes = copy.deepcopy(entry._attributes) yield entry except error.LDAPNoSuchObjectError: # If the search returned without results, "return" an empty generator. return
def handle_ldap_error(err): """Given an LDAP error code, raise an error if needed. :param err: The error code returned by the library. :type err: int """ if err == libldap.LDAP_SUCCESS: return error_string = compat._decode_utf8(ffi.string(libldap.ldap_err2string(err))) if err == libldap.LDAP_NO_SUCH_OBJECT: raise error.LDAPNoSuchObjectError(error_string) elif err == libldap.LDAP_INVALID_CREDENTIALS: raise error.LDAPInvalidCredentialsError(error_string) elif err == libldap.LDAP_SERVER_DOWN: raise error.LDAPServerDownError(error_string) else: raise error.LDAPError(error_string)
def _set_ldap_values(self, values): self._values = set([compat._decode_utf8(v) for v in values])
def _raw_search(self, search_filter=None, retrieve_attributes=None, base=None, scope=libldap.LDAP_SCOPE_SUBTREE, retrieve_operational_attributes=False): """ Raw wrapper around OpenLDAP ldap_search_ext_s. :param search_filter: Filter expression to use. OpenLDAP default used if None is given. :type search_filter: List of str :param retrieve_attributes: List of attributes to retrieve. If None is given, all user attributes are retrieved. :type retrieve_attributes: List of str :param base: Search base for the query. :type base: str :param scope: The search scope in the LDAP tree :param retrieve_operational_attributes: Retrieve operational attributes of entries in addition to user attributes if retrieve_attributes is not set. """ search_result_p = ffi.new("LDAPMessage **") # Keep around references to pointers to owned memory with data that is # still needed. prevent_garbage_collection = [] if retrieve_attributes is None: retrieve_attributes = [ compat._decode_utf8(ffi.string(libldap.LDAP_ALL_USER_ATTRIBUTES))] if retrieve_operational_attributes: retrieve_attributes.append( compat._decode_utf8(ffi.string(libldap.LDAP_ALL_OPERATIONAL_ATTRIBUTES))) attrs_p = ffi.new("char*[{}]".format(len(retrieve_attributes) + 1)) for i, a in enumerate(retrieve_attributes): attr_p = ffi.new("char[]", compat._encode_utf8(a)) prevent_garbage_collection.append(attr_p) attrs_p[i] = attr_p attrs_p[len(retrieve_attributes)] = ffi.NULL err = libldap.ldap_search_ext_s( self._ld, compat._encode_utf8(base or self._base), scope, (compat._encode_utf8(search_filter) if search_filter is not None else ffi.NULL), attrs_p, 0, ffi.NULL, ffi.NULL, ffi.NULL, # TODO: Implement timeouts 0,#libldap.LDAP_NO_LIMIT, search_result_p) handle_ldap_error(err) search_result = search_result_p[0] current_entry = libldap.ldap_first_entry(self._ld, search_result) while current_entry != ffi.NULL: dn = ffi.string(libldap.ldap_get_dn(self._ld, current_entry)) attribute_dict = {} ber_p = ffi.new("BerElement **") current_attribute = libldap.ldap_first_attribute(self._ld, current_entry, ber_p) while current_attribute != ffi.NULL: current_attribute_str = ffi.string(current_attribute) attribute_dict[current_attribute_str] = [] values_p = libldap.ldap_get_values_len(self._ld, current_entry, current_attribute) for i in range(0, libldap.ldap_count_values_len(values_p)): val = ffi.buffer(values_p[i].bv_val, values_p[i].bv_len)[:] attribute_dict[current_attribute_str].append(val) libldap.ldap_memfree(current_attribute) current_attribute = libldap.ldap_next_attribute(self._ld, current_entry, ber_p[0]) libldap.ber_free(ber_p[0], 0) yield (dn, attribute_dict) current_entry = libldap.ldap_next_entry(self._ld, current_entry) libldap.ldap_msgfree(search_result)