Perform an AD search

        :param str base_dn: The base DN to search within
        :param str search_filter: The search filter to apply, such as:
          *objectClass=person*
        :param list attributes: Object attributes to populate, defaults to all

def search(self, base_dn, search_filter, attributes=()):
        """Perform an AD search

        :param str base_dn: The base DN to search within
        :param str search_filter: The search filter to apply, such as:
          *objectClass=person*
        :param list attributes: Object attributes to populate, defaults to all
        """
        results = []
        page = 0
        while page == 0 or self.sprc.cookie:
            page += 1
            #pylint: disable=no-member
            message_id = self.ldap.search_ext(base_dn, ldap.SCOPE_SUBTREE,
                                              search_filter, attributes,
                                              serverctrls=[self.sprc])
            #pylint: enable=no-member
            data, server_controls = self.ldap.result3(message_id)[1::2]
            self.sprc.cookie = server_controls[0].cookie
            logging.debug('%s - Page %s results: %s',  \
                          self.__class__.__name__, page, ', '.join(k[0] for k in data))
            results += [u for u in data]

        return results