static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
					struct lsa_EnumTrustedDomainsEx *r)
{
	struct dcesrv_handle *policy_handle;
	struct lsa_TrustDomainInfoInfoEx *entries;
	struct lsa_policy_state *policy_state;
	struct ldb_message **domains;
	const char *attrs[] = {
		"flatname",
		"trustPartner",
		"securityIdentifier",
		"trustDirection",
		"trustType",
		"trustAttributes",
		NULL
	};
	NTSTATUS nt_status;

	int count, i;

	*r->out.resume_handle = 0;

	r->out.domains->domains = NULL;
	r->out.domains->count = 0;

	DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);

	policy_state = policy_handle->data;

	/* search for all users in this domain. This could possibly be cached and
	   resumed based on resume_key */
	count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
			     "objectclass=trustedDomain");
	if (count < 0) {
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	/* convert to lsa_DomainInformation format */
	entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
	if (!entries) {
		return NT_STATUS_NO_MEMORY;
	}
	for (i=0;i<count;i++) {
		nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
		if (!NT_STATUS_IS_OK(nt_status)) {
			return nt_status;
		}
	}

	/* sort the results by name */
	TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);

	if (*r->in.resume_handle >= count) {
		*r->out.resume_handle = -1;

		return NT_STATUS_NO_MORE_ENTRIES;
	}

	/* return the rest, limit by max_size. Note that we
	   use the w2k3 element size value of 60 */
	r->out.domains->count = count - *r->in.resume_handle;
	r->out.domains->count = MIN(r->out.domains->count,
				 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));

	r->out.domains->domains = entries + *r->in.resume_handle;

	if (r->out.domains->count < count - *r->in.resume_handle) {
		*r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
		return STATUS_MORE_ENTRIES;
	}

	*r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;

	return NT_STATUS_OK;
}
static NTSTATUS dcesrv_lsa_EnumTrustedDomainsEx(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
					struct lsa_EnumTrustedDomainsEx *r)
{
	struct dcesrv_handle *policy_handle;
	struct lsa_TrustDomainInfoInfoEx *entries;
	struct lsa_policy_state *policy_state;
	struct ldb_message **domains;
	const char *attrs[] = {
		"flatname",
		"trustPartner",
		"securityIdentifier",
		"trustDirection",
		"trustType",
		"trustAttributes",
		NULL
	};
	NTSTATUS nt_status;

	int count, i;

	*r->out.resume_handle = 0;

	r->out.domains->domains = NULL;
	r->out.domains->count = 0;

	DCESRV_PULL_HANDLE(policy_handle, r->in.handle, LSA_HANDLE_POLICY);

	policy_state = policy_handle->data;

	 
	count = gendb_search(policy_state->sam_ldb, mem_ctx, policy_state->system_dn, &domains, attrs,
			     "objectclass=trustedDomain");
	if (count < 0) {
		return NT_STATUS_INTERNAL_DB_CORRUPTION;
	}

	 
	entries = talloc_array(mem_ctx, struct lsa_TrustDomainInfoInfoEx, count);
	if (!entries) {
		return NT_STATUS_NO_MEMORY;
	}
	for (i=0;i<count;i++) {
		nt_status = fill_trust_domain_ex(mem_ctx, domains[i], &entries[i]);
		if (!NT_STATUS_IS_OK(nt_status)) {
			return nt_status;
		}
	}

	 
	TYPESAFE_QSORT(entries, count, compare_TrustDomainInfoInfoEx);

	if (*r->in.resume_handle >= count) {
		*r->out.resume_handle = -1;

		return NT_STATUS_NO_MORE_ENTRIES;
	}

	 
	r->out.domains->count = count - *r->in.resume_handle;
	r->out.domains->count = MIN(r->out.domains->count,
				 1+(r->in.max_size/LSA_ENUM_TRUST_DOMAIN_EX_MULTIPLIER));

	r->out.domains->domains = entries + *r->in.resume_handle;

	if (r->out.domains->count < count - *r->in.resume_handle) {
		*r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;
		return STATUS_MORE_ENTRIES;
	}

	*r->out.resume_handle = *r->in.resume_handle + r->out.domains->count;

	return NT_STATUS_OK;
}