static int check_spn_direct_collision(struct ldb_context *ldb,
				      TALLOC_CTX *mem_ctx,
				      const char *spn,
				      struct ldb_dn *target_dn)
{
	int ret;
	TALLOC_CTX *tmp_ctx = NULL;
	struct ldb_dn *colliding_dn = NULL;
	const char *target_dnstr = NULL;
	const char *colliding_dnstr = NULL;

	tmp_ctx = talloc_new(mem_ctx);
	if (tmp_ctx == NULL) {
		return ldb_oom(ldb);
	}

	ret = get_spn_dn(ldb, tmp_ctx, spn, &colliding_dn);
	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		DBG_DEBUG("SPN '%s' not found (good)\n", spn);
		talloc_free(tmp_ctx);
		return LDB_SUCCESS;
	}
	if (ret != LDB_SUCCESS) {
		DBG_ERR("SPN '%s' search error %d\n", spn, ret);
		talloc_free(tmp_ctx);
		if (ret == LDB_ERR_COMPARE_TRUE) {
			/*
			 * COMPARE_TRUE has special meaning here and we don't
			 * want to return it by mistake.
			 */
			ret = LDB_ERR_OPERATIONS_ERROR;
		}
		return ret;
	}
	/*
	 * We have found this exact SPN. This is mostly harmless (depend on
	 * ADD vs REPLACE) when the spn is being put on the object that
	 * already has, so we let it through to succeed or fail as some other
	 * module sees fit.
	 */
	target_dnstr = ldb_dn_get_linearized(target_dn);
	ret = ldb_dn_compare(colliding_dn, target_dn);
	if (ret != 0) {
		colliding_dnstr = ldb_dn_get_linearized(colliding_dn);
		DBG_ERR("SPN '%s' is on '%s' so it can't be "
			"added to '%s'\n",
			spn,
			colliding_dnstr,
			target_dnstr);
		ldb_asprintf_errstring(ldb,
				       "samldb: spn[%s] would cause a conflict",
				       spn);
		talloc_free(tmp_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	DBG_INFO("SPN '%s' is already on '%s'\n",
		 spn, target_dnstr);
	talloc_free(tmp_ctx);
	return LDB_ERR_COMPARE_TRUE;
}
static int check_spn_direct_collision(struct ldb_context *ldb,
				      TALLOC_CTX *mem_ctx,
				      const char *spn,
				      struct ldb_dn *target_dn)
{
	int ret;
	TALLOC_CTX *tmp_ctx = NULL;
	struct ldb_dn *colliding_dn = NULL;
	const char *target_dnstr = NULL;
	const char *colliding_dnstr = NULL;

	tmp_ctx = talloc_new(mem_ctx);
	if (tmp_ctx == NULL) {
		return ldb_oom(ldb);
	}

	ret = get_spn_dn(ldb, tmp_ctx, spn, &colliding_dn);
	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		DBG_DEBUG("SPN '%s' not found (good)\n", spn);
		talloc_free(tmp_ctx);
		return LDB_SUCCESS;
	}
	if (ret != LDB_SUCCESS) {
		DBG_ERR("SPN '%s' search error %d\n", spn, ret);
		talloc_free(tmp_ctx);
		if (ret == LDB_ERR_COMPARE_TRUE) {
			 
			ret = LDB_ERR_OPERATIONS_ERROR;
		}
		return ret;
	}
	 
	target_dnstr = ldb_dn_get_linearized(target_dn);
	ret = ldb_dn_compare(colliding_dn, target_dn);
	if (ret != 0) {
		colliding_dnstr = ldb_dn_get_linearized(colliding_dn);
		DBG_ERR("SPN '%s' is on '%s' so it can't be "
			"added to '%s'\n",
			spn,
			colliding_dnstr,
			target_dnstr);
		ldb_asprintf_errstring(ldb,
				       "samldb: spn[%s] would cause a conflict",
				       spn);
		talloc_free(tmp_ctx);
		return LDB_ERR_CONSTRAINT_VIOLATION;
	}

	DBG_INFO("SPN '%s' is already on '%s'\n",
		 spn, target_dnstr);
	talloc_free(tmp_ctx);
	return LDB_ERR_COMPARE_TRUE;
}