'Query an LDAP server with the filter argument and scope subtree.
Allow for all authentication methods of the simple authentication
method:
- authenticated bind (non-empty binddn + valid password)
- anonymous bind (empty binddn + empty password)
- unauthenticated authentication (non-empty binddn + empty password)
.. seealso::
:rfc:`4513#section-5.1` - LDAP: Simple Authentication Method.
:param dict conf: LDAP configuration
:param filter: valid LDAP filter
:param list retrieve_attributes: LDAP attributes to be retrieved.         If not specified, return all attributes.
:return: ldap entries
:rtype: list of tuples (dn, attrs)'

def query(self, conf, filter, retrieve_attributes=None):

    results = []
    try:
        conn = self.connect(conf)
        ldap_password = (conf['ldap_password'] or '')
        ldap_binddn = (conf['ldap_binddn'] or '')
        conn.simple_bind_s(ldap_binddn.encode('utf-8'), ldap_password.encode('utf-8'))
        results = conn.search_st(conf['ldap_base'].encode('utf-8'), ldap.SCOPE_SUBTREE, filter, retrieve_attributes, timeout=60)
        conn.unbind()
    except ldap.INVALID_CREDENTIALS:
        _logger.error('LDAP    bind    failed.')
    except ldap.LDAPError as e:
        _logger.error('An    LDAP    exception    occurred:    %s', e)
    return results
