static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv,
					 struct ldb_kv_context *ctx)
{
	struct ldb_message *msg, *filtered_msg;
	struct ldb_context *ldb = ldb_module_get_ctx(ctx->module);
	const char *dn_linearized;
	const char *msg_dn_linearized;
	int ret;
	bool matched;

	msg = ldb_msg_new(ctx);
	if (!msg) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	ret = ldb_kv_search_dn1(ctx->module,
				ctx->base,
				msg,
				LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC |
				LDB_UNPACK_DATA_FLAG_READ_LOCKED);

	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		if (ldb_kv->check_base == false) {
			/*
			 * In this case, we are done, as no base
			 * checking is allowed in this DB
			 */
			talloc_free(msg);
			return LDB_SUCCESS;
		}
		ldb_asprintf_errstring(ldb,
				       "No such Base DN: %s",
				       ldb_dn_get_linearized(ctx->base));
	}
	if (ret != LDB_SUCCESS) {
		talloc_free(msg);
		return ret;
	}


	/*
	 * We use this, not ldb_match_msg_error() as we know
	 * we matched on the scope BASE, as we just fetched
	 * the base DN
	 */

	ret = ldb_match_message(ldb, msg,
				ctx->tree,
				ctx->scope,
				&matched);
	if (ret != LDB_SUCCESS) {
		talloc_free(msg);
		return ret;
	}
	if (!matched) {
		talloc_free(msg);
		return LDB_SUCCESS;
	}

	dn_linearized = ldb_dn_get_linearized(ctx->base);
	msg_dn_linearized = ldb_dn_get_linearized(msg->dn);

	filtered_msg = ldb_msg_new(ctx);
	if (filtered_msg == NULL) {
		talloc_free(msg);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	if (strcmp(dn_linearized, msg_dn_linearized) == 0) {
		/*
		 * If the DN is exactly the same string, then
		 * re-use the full incoming DN for the
		 * returned result, as it has already been
		 * casefolded
		 */
		filtered_msg->dn = ldb_dn_copy(filtered_msg, ctx->base);
	}

	/*
	 * If the ldb_dn_copy() failed, or if we did not choose that
	 * optimisation (filtered_msg is zeroed at allocation),
	 * steal the one from the unpack
	 */
	if (filtered_msg->dn == NULL) {
		filtered_msg->dn = talloc_steal(filtered_msg, msg->dn);
	}

	/*
	 * filter the attributes that the user wants.
	 */
	ret = ldb_kv_filter_attrs(ldb, msg, ctx->attrs, filtered_msg);
	if (ret == -1) {
		talloc_free(msg);
		filtered_msg = NULL;
		return LDB_ERR_OPERATIONS_ERROR;
	}

	/*
	 * Remove any extended components possibly copied in from
	 * msg->dn, we just want the casefold components
	 */
	ldb_dn_remove_extended_components(filtered_msg->dn);
	talloc_free(msg);

	ret = ldb_module_send_entry(ctx->req, filtered_msg, NULL);
	if (ret != LDB_SUCCESS) {
		/* Regardless of success or failure, the msg
		 * is the callbacks responsiblity, and should
		 * not be talloc_free()'ed */
		ctx->request_terminated = true;
		return ret;
	}

	return LDB_SUCCESS;
}
static int ldb_kv_search_and_return_base(struct ldb_kv_private *ldb_kv,
					 struct ldb_kv_context *ctx)
{
	struct ldb_message *msg, *filtered_msg;
	struct ldb_context *ldb = ldb_module_get_ctx(ctx->module);
	const char *dn_linearized;
	const char *msg_dn_linearized;
	int ret;
	bool matched;

	msg = ldb_msg_new(ctx);
	if (!msg) {
		return LDB_ERR_OPERATIONS_ERROR;
	}
	ret = ldb_kv_search_dn1(ctx->module,
				ctx->base,
				msg,
				LDB_UNPACK_DATA_FLAG_NO_VALUES_ALLOC |
				LDB_UNPACK_DATA_FLAG_READ_LOCKED);

	if (ret == LDB_ERR_NO_SUCH_OBJECT) {
		if (ldb_kv->check_base == false) {
			 
			talloc_free(msg);
			return LDB_SUCCESS;
		}
		ldb_asprintf_errstring(ldb,
				       "No such Base DN: %s",
				       ldb_dn_get_linearized(ctx->base));
	}
	if (ret != LDB_SUCCESS) {
		talloc_free(msg);
		return ret;
	}


	 

	ret = ldb_match_message(ldb, msg,
				ctx->tree,
				ctx->scope,
				&matched);
	if (ret != LDB_SUCCESS) {
		talloc_free(msg);
		return ret;
	}
	if (!matched) {
		talloc_free(msg);
		return LDB_SUCCESS;
	}

	dn_linearized = ldb_dn_get_linearized(ctx->base);
	msg_dn_linearized = ldb_dn_get_linearized(msg->dn);

	filtered_msg = ldb_msg_new(ctx);
	if (filtered_msg == NULL) {
		talloc_free(msg);
		return LDB_ERR_OPERATIONS_ERROR;
	}

	if (strcmp(dn_linearized, msg_dn_linearized) == 0) {
		 
		filtered_msg->dn = ldb_dn_copy(filtered_msg, ctx->base);
	}

	 
	if (filtered_msg->dn == NULL) {
		filtered_msg->dn = talloc_steal(filtered_msg, msg->dn);
	}

	 
	ret = ldb_kv_filter_attrs(ldb, msg, ctx->attrs, filtered_msg);
	if (ret == -1) {
		talloc_free(msg);
		filtered_msg = NULL;
		return LDB_ERR_OPERATIONS_ERROR;
	}

	 
	ldb_dn_remove_extended_components(filtered_msg->dn);
	talloc_free(msg);

	ret = ldb_module_send_entry(ctx->req, filtered_msg, NULL);
	if (ret != LDB_SUCCESS) {
		 
		ctx->request_terminated = true;
		return ret;
	}

	return LDB_SUCCESS;
}