Exemple #1
0
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)
Exemple #2
0
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)
Exemple #3
0
    def _raw_search(self, search_filter=None, retrieve_attributes=None,
            base=None, scope=libldap.LDAP_SCOPE_SUBTREE):
        """
        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 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
        """
        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 not None:
            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
        else:
            attrs_p = 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(self._ld, current_entry,
                        current_attribute)
                for i in range(0, libldap.ldap_count_values(values_p)):
                    attribute_dict[current_attribute_str].append(
                            ffi.string(values_p[i]))

                current_attribute = libldap.ldap_next_attribute(self._ld,
                        current_entry, ber_p[0])
            # TODO: Call ber_free on ber_p[0]

            yield (dn, attribute_dict)
            current_entry = libldap.ldap_next_entry(self._ld, current_entry)
Exemple #4
0
    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)