static bool pdb_samba_dsdb_search_filter(struct pdb_methods *m,
				     struct pdb_search *search,
				     struct pdb_samba_dsdb_search_state **pstate,
				     const char *exp_fmt, ...)
{
	struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
		m->private_data, struct pdb_samba_dsdb_state);
	struct pdb_samba_dsdb_search_state *sstate;
	const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
				 "userAccountControl", "description", NULL };
	struct ldb_result *res;
	int i, rc, num_users;

	va_list ap;
	char *expression = NULL;

	TALLOC_CTX *tmp_ctx = talloc_stackframe();
	if (!tmp_ctx) {
		return false;
	}

	va_start(ap, exp_fmt);
	expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
	va_end(ap);

	if (!expression) {
		talloc_free(tmp_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	sstate = talloc_zero(tmp_ctx, struct pdb_samba_dsdb_search_state);
	if (sstate == NULL) {
		talloc_free(tmp_ctx);
		return false;
	}

	rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
	if (rc != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		DEBUG(10, ("dsdb_search failed: %s\n",
			   ldb_errstring(state->ldb)));
		return false;
	}

	num_users = res->count;

	sstate->entries = talloc_array(sstate, struct samr_displayentry,
				       num_users);
	if (sstate->entries == NULL) {
		talloc_free(tmp_ctx);
		DEBUG(10, ("talloc failed\n"));
		return false;
	}

	sstate->num_entries = 0;

	for (i=0; i<num_users; i++) {
		struct samr_displayentry *e;
		struct dom_sid *sid;

		e = &sstate->entries[sstate->num_entries];

		e->idx = sstate->num_entries;
		sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
		if (!sid) {
			talloc_free(tmp_ctx);
			DEBUG(10, ("Could not pull SID\n"));
			return false;
		}
		sid_peek_rid(sid, &e->rid);

		e->acct_flags = samdb_result_acct_flags(res->msgs[i], "userAccountControl");
		e->account_name = ldb_msg_find_attr_as_string(
			res->msgs[i], "samAccountName", NULL);
		if (e->account_name == NULL) {
			talloc_free(tmp_ctx);
			return false;
		}
		e->fullname = ldb_msg_find_attr_as_string(
                        res->msgs[i], "displayName", "");
		e->description = ldb_msg_find_attr_as_string(
                        res->msgs[i], "description", "");

		sstate->num_entries += 1;
		if (sstate->num_entries >= num_users) {
			break;
		}
	}
	talloc_steal(sstate->entries, res->msgs);
	search->private_data = talloc_steal(search, sstate);
	search->next_entry = pdb_samba_dsdb_next_entry;
	search->search_end = pdb_samba_dsdb_search_end;
	*pstate = sstate;
	talloc_free(tmp_ctx);
	return true;
}
static bool pdb_samba_dsdb_search_filter(struct pdb_methods *m,
				     struct pdb_search *search,
				     struct pdb_samba_dsdb_search_state **pstate,
				     const char *exp_fmt, ...)
{
	struct pdb_samba_dsdb_state *state = talloc_get_type_abort(
		m->private_data, struct pdb_samba_dsdb_state);
	struct pdb_samba_dsdb_search_state *sstate;
	const char * attrs[] = { "objectSid", "sAMAccountName", "displayName",
				 "userAccountControl", "description", NULL };
	struct ldb_result *res;
	int i, rc, num_users;

	va_list ap;
	char *expression = NULL;

	TALLOC_CTX *tmp_ctx = talloc_stackframe();
	if (!tmp_ctx) {
		return false;
	}

	va_start(ap, exp_fmt);
	expression = talloc_vasprintf(tmp_ctx, exp_fmt, ap);
	va_end(ap);

	if (!expression) {
		talloc_free(tmp_ctx);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	sstate = talloc_zero(tmp_ctx, struct pdb_samba_dsdb_search_state);
	if (sstate == NULL) {
		talloc_free(tmp_ctx);
		return false;
	}

	rc = dsdb_search(state->ldb, tmp_ctx, &res, ldb_get_default_basedn(state->ldb), LDB_SCOPE_SUBTREE, attrs, 0, "%s", expression);
	if (rc != LDB_SUCCESS) {
		talloc_free(tmp_ctx);
		DEBUG(10, ("dsdb_search failed: %s\n",
			   ldb_errstring(state->ldb)));
		return false;
	}

	num_users = res->count;

	sstate->entries = talloc_array(sstate, struct samr_displayentry,
				       num_users);
	if (sstate->entries == NULL) {
		talloc_free(tmp_ctx);
		DEBUG(10, ("talloc failed\n"));
		return false;
	}

	sstate->num_entries = 0;

	for (i=0; i<num_users; i++) {
		struct samr_displayentry *e;
		struct dom_sid *sid;

		e = &sstate->entries[sstate->num_entries];

		e->idx = sstate->num_entries;
		sid = samdb_result_dom_sid(tmp_ctx, res->msgs[i], "objectSid");
		if (!sid) {
			talloc_free(tmp_ctx);
			DEBUG(10, ("Could not pull SID\n"));
			return false;
		}
		sid_peek_rid(sid, &e->rid);

		e->acct_flags = samdb_result_acct_flags(res->msgs[i], "userAccountControl");
		e->account_name = ldb_msg_find_attr_as_string(
			res->msgs[i], "samAccountName", NULL);
		if (e->account_name == NULL) {
			talloc_free(tmp_ctx);
			return false;
		}
		e->fullname = ldb_msg_find_attr_as_string(
                        res->msgs[i], "displayName", "");
		e->description = ldb_msg_find_attr_as_string(
                        res->msgs[i], "description", "");

		sstate->num_entries += 1;
		if (sstate->num_entries >= num_users) {
			break;
		}
	}
	talloc_steal(sstate->entries, res->msgs);
	search->private_data = talloc_steal(search, sstate);
	search->next_entry = pdb_samba_dsdb_next_entry;
	search->search_end = pdb_samba_dsdb_search_end;
	*pstate = sstate;
	talloc_free(tmp_ctx);
	return true;
}