'Search for all matching objects under dn using the query.
Args:
dn -- dn to search under
scope -- only SCOPE_BASE and SCOPE_SUBTREE are supported
query -- query to filter objects by
fields -- fields to return. Returns all fields if not specified'

def search_s(self, dn, scope, query=None, fields=None):

    if server_fail:
        raise SERVER_DOWN()
    if ((scope != SCOPE_BASE) and (scope != SCOPE_SUBTREE)):
        raise NotImplementedError(str(scope))
    store = Store.instance()
    if (scope == SCOPE_BASE):
        pattern = ('%s%s' % (self.__prefix, dn))
        keys = store.keys(pattern)
    else:
        keys = store.keys(('%s*%s' % (self.__prefix, dn)))
    if (not keys):
        raise NO_SUCH_OBJECT()
    objects = []
    for key in keys:
        attrs = store.hgetall(key)
        attrs = {k: _from_json(v) for (k, v) in attrs.items()}
        if ((not query) or _match_query(query, attrs)):
            attrs = {k: v for (k, v) in attrs.items() if ((not fields) or (k in fields))}
            objects.append((key[len(self.__prefix):], attrs))
    return objects
