int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn,
				   struct ldb_dn **parent_dn, const char **errstring)
{
	TALLOC_CTX *local_ctx;
	struct ldb_dn *sdn = dn;
	struct ldb_result *res = NULL;
	int ret = LDB_SUCCESS;
	const char *attrs[] = { NULL };

	local_ctx = talloc_new(mem_ctx);
	if (local_ctx == NULL) return ldb_oom(ldb);

	while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
		ret = ldb_search(ldb, local_ctx, &res, sdn, LDB_SCOPE_BASE, attrs,
				 "(|(objectClass=domain)(objectClass=builtinDomain))");
		if (ret == LDB_SUCCESS) {
			if (res->count == 1) {
				break;
			}
		} else {
			break;
		}
	}

	if (ret != LDB_SUCCESS) {
		*errstring = talloc_asprintf(mem_ctx, "Error searching for parent domain of %s, failed searching for %s: %s",
					     ldb_dn_get_linearized(dn),
					     ldb_dn_get_linearized(sdn),
					     ldb_errstring(ldb));
		talloc_free(local_ctx);
		return ret;
	}
	/* should never be true with 'ret=LDB_SUCCESS', here to satisfy clang */
	if (res == NULL) {
		talloc_free(local_ctx);
		return LDB_ERR_OTHER;
	}
	if (res->count != 1) {
		*errstring = talloc_asprintf(mem_ctx, "Invalid dn (%s), not child of a domain object",
					     ldb_dn_get_linearized(dn));
		DEBUG(0,(__location__ ": %s\n", *errstring));
		talloc_free(local_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	*parent_dn = talloc_steal(mem_ctx, res->msgs[0]->dn);
	talloc_free(local_ctx);
	return ret;
}
int samdb_search_for_parent_domain(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_dn *dn,
				   struct ldb_dn **parent_dn, const char **errstring)
{
	TALLOC_CTX *local_ctx;
	struct ldb_dn *sdn = dn;
	struct ldb_result *res = NULL;
	int ret = LDB_SUCCESS;
	const char *attrs[] = { NULL };

	local_ctx = talloc_new(mem_ctx);
	if (local_ctx == NULL) return ldb_oom(ldb);

	while ((sdn = ldb_dn_get_parent(local_ctx, sdn))) {
		ret = ldb_search(ldb, local_ctx, &res, sdn, LDB_SCOPE_BASE, attrs,
				 "(|(objectClass=domain)(objectClass=builtinDomain))");
		if (ret == LDB_SUCCESS) {
			if (res->count == 1) {
				break;
			}
		} else {
			break;
		}
	}

	if (ret != LDB_SUCCESS) {
		*errstring = talloc_asprintf(mem_ctx, "Error searching for parent domain of %s, failed searching for %s: %s",
					     ldb_dn_get_linearized(dn),
					     ldb_dn_get_linearized(sdn),
					     ldb_errstring(ldb));
		talloc_free(local_ctx);
		return ret;
	}
	 
	if (res == NULL) {
		talloc_free(local_ctx);
		return LDB_ERR_OTHER;
	}
	if (res->count != 1) {
		*errstring = talloc_asprintf(mem_ctx, "Invalid dn (%s), not child of a domain object",
					     ldb_dn_get_linearized(dn));
		DEBUG(0,(__location__ ": %s\n", *errstring));
		talloc_free(local_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	*parent_dn = talloc_steal(mem_ctx, res->msgs[0]->dn);
	talloc_free(local_ctx);
	return ret;
}