static int replmd_replicated_apply_search_for_parent_callback(struct ldb_request *req,
							      struct ldb_reply *ares)
{
	struct replmd_replicated_request *ar = talloc_get_type(req->context,
					       struct replmd_replicated_request);
	int ret;

	if (!ares) {
		return ldb_module_done(ar->req, NULL, NULL,
					LDB_ERR_OPERATIONS_ERROR);
	}

	/*
	 * The error NO_SUCH_OBJECT is not expected, unless the search
	 * base is the partition DN, and that case doesn't happen here
	 * because then we wouldn't get a parent_guid_value in any
	 * case.
	 */
	if (ares->error != LDB_SUCCESS) {
		return ldb_module_done(ar->req, ares->controls,
					ares->response, ares->error);
	}

	switch (ares->type) {
	case LDB_REPLY_ENTRY:
	{
		struct ldb_message *parent_msg = ares->message;
		struct ldb_message *msg = ar->objs->objects[ar->index_current].msg;
		struct ldb_dn *parent_dn = NULL;
		int comp_num;

		if (!ldb_msg_check_string_attribute(msg, "isDeleted", "TRUE")
		    && ldb_msg_check_string_attribute(parent_msg, "isDeleted", "TRUE")) {
			/* Per MS-DRSR 4.1.10.6.10
			 * FindBestParentObject we need to move this
			 * new object under a deleted object to
			 * lost-and-found */
			struct ldb_dn *nc_root;

			ret = dsdb_find_nc_root(ldb_module_get_ctx(ar->module), msg, msg->dn, &nc_root);
			if (ret == LDB_ERR_NO_SUCH_OBJECT) {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "No suitable NC root found for %s.  "
						       "We need to move this object because parent object %s "
						       "is deleted, but this object is not.",
						       ldb_dn_get_linearized(msg->dn),
						       ldb_dn_get_linearized(parent_msg->dn));
				return ldb_module_done(ar->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
			} else if (ret != LDB_SUCCESS) {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "Unable to find NC root for %s: %s. "
						       "We need to move this object because parent object %s "
						       "is deleted, but this object is not.",
						       ldb_dn_get_linearized(msg->dn),
						       ldb_errstring(ldb_module_get_ctx(ar->module)),
						       ldb_dn_get_linearized(parent_msg->dn));
				return ldb_module_done(ar->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
			}

			ret = dsdb_wellknown_dn(ldb_module_get_ctx(ar->module), msg,
						nc_root,
						DS_GUID_LOSTANDFOUND_CONTAINER,
						&parent_dn);
			if (ret != LDB_SUCCESS) {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "Unable to find LostAndFound Container for %s "
						       "in partition %s: %s. "
						       "We need to move this object because parent object %s "
						       "is deleted, but this object is not.",
						       ldb_dn_get_linearized(msg->dn), ldb_dn_get_linearized(nc_root),
						       ldb_errstring(ldb_module_get_ctx(ar->module)),
						       ldb_dn_get_linearized(parent_msg->dn));
				return ldb_module_done(ar->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
			}
			ar->objs->objects[ar->index_current].last_known_parent
				= talloc_steal(ar->objs->objects[ar->index_current].msg, parent_msg->dn);

		} else {
			parent_dn
				= talloc_steal(ar->objs->objects[ar->index_current].msg, parent_msg->dn);

		}
		ar->objs->objects[ar->index_current].local_parent_dn = parent_dn;

		comp_num = ldb_dn_get_comp_num(msg->dn);
		if (comp_num > 1) {
			if (!ldb_dn_remove_base_components(msg->dn, comp_num - 1)) {
				talloc_free(ares);
				return ldb_module_done(ar->req, NULL, NULL, ldb_module_operr(ar->module));
			}
		}
		if (!ldb_dn_add_base(msg->dn, parent_dn)) {
			talloc_free(ares);
			return ldb_module_done(ar->req, NULL, NULL, ldb_module_operr(ar->module));
		}
		break;
	}
	case LDB_REPLY_REFERRAL:
		/* we ignore referrals */
		break;

	case LDB_REPLY_DONE:

		if (ar->objs->objects[ar->index_current].local_parent_dn == NULL) {
			struct GUID_txt_buf str_buf;
			if (ar->search_msg != NULL) {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "No parent with GUID %s found for object locally known as %s",
						       GUID_buf_string(ar->objs->objects[ar->index_current].parent_guid, &str_buf),
						       ldb_dn_get_linearized(ar->search_msg->dn));
			} else {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "No parent with GUID %s found for object remotely known as %s",
						       GUID_buf_string(ar->objs->objects[ar->index_current].parent_guid, &str_buf),
						       ldb_dn_get_linearized(ar->objs->objects[ar->index_current].msg->dn));
			}

			/*
			 * This error code is really important, as it
			 * is the flag back to the callers to retry
			 * this with DRSUAPI_DRS_GET_ANC, and so get
			 * the parent objects before the child
			 * objects
			 */
			return ldb_module_done(ar->req, NULL, NULL,
					       replmd_replicated_request_werror(ar, WERR_DS_DRA_MISSING_PARENT));
		}

		if (ar->search_msg != NULL) {
			ret = replmd_replicated_apply_merge(ar);
		} else {
			ret = replmd_replicated_apply_add(ar);
		}
		if (ret != LDB_SUCCESS) {
			return ldb_module_done(ar->req, NULL, NULL, ret);
		}
	}

	talloc_free(ares);
	return LDB_SUCCESS;
}
static int replmd_replicated_apply_search_for_parent_callback(struct ldb_request *req,
							      struct ldb_reply *ares)
{
	struct replmd_replicated_request *ar = talloc_get_type(req->context,
					       struct replmd_replicated_request);
	int ret;

	if (!ares) {
		return ldb_module_done(ar->req, NULL, NULL,
					LDB_ERR_OPERATIONS_ERROR);
	}

	 
	if (ares->error != LDB_SUCCESS) {
		return ldb_module_done(ar->req, ares->controls,
					ares->response, ares->error);
	}

	switch (ares->type) {
	case LDB_REPLY_ENTRY:
	{
		struct ldb_message *parent_msg = ares->message;
		struct ldb_message *msg = ar->objs->objects[ar->index_current].msg;
		struct ldb_dn *parent_dn = NULL;
		int comp_num;

		if (!ldb_msg_check_string_attribute(msg, "isDeleted", "TRUE")
		    && ldb_msg_check_string_attribute(parent_msg, "isDeleted", "TRUE")) {
			 
			struct ldb_dn *nc_root;

			ret = dsdb_find_nc_root(ldb_module_get_ctx(ar->module), msg, msg->dn, &nc_root);
			if (ret == LDB_ERR_NO_SUCH_OBJECT) {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "No suitable NC root found for %s.  "
						       "We need to move this object because parent object %s "
						       "is deleted, but this object is not.",
						       ldb_dn_get_linearized(msg->dn),
						       ldb_dn_get_linearized(parent_msg->dn));
				return ldb_module_done(ar->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
			} else if (ret != LDB_SUCCESS) {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "Unable to find NC root for %s: %s. "
						       "We need to move this object because parent object %s "
						       "is deleted, but this object is not.",
						       ldb_dn_get_linearized(msg->dn),
						       ldb_errstring(ldb_module_get_ctx(ar->module)),
						       ldb_dn_get_linearized(parent_msg->dn));
				return ldb_module_done(ar->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
			}

			ret = dsdb_wellknown_dn(ldb_module_get_ctx(ar->module), msg,
						nc_root,
						DS_GUID_LOSTANDFOUND_CONTAINER,
						&parent_dn);
			if (ret != LDB_SUCCESS) {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "Unable to find LostAndFound Container for %s "
						       "in partition %s: %s. "
						       "We need to move this object because parent object %s "
						       "is deleted, but this object is not.",
						       ldb_dn_get_linearized(msg->dn), ldb_dn_get_linearized(nc_root),
						       ldb_errstring(ldb_module_get_ctx(ar->module)),
						       ldb_dn_get_linearized(parent_msg->dn));
				return ldb_module_done(ar->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR);
			}
			ar->objs->objects[ar->index_current].last_known_parent
				= talloc_steal(ar->objs->objects[ar->index_current].msg, parent_msg->dn);

		} else {
			parent_dn
				= talloc_steal(ar->objs->objects[ar->index_current].msg, parent_msg->dn);

		}
		ar->objs->objects[ar->index_current].local_parent_dn = parent_dn;

		comp_num = ldb_dn_get_comp_num(msg->dn);
		if (comp_num > 1) {
			if (!ldb_dn_remove_base_components(msg->dn, comp_num - 1)) {
				talloc_free(ares);
				return ldb_module_done(ar->req, NULL, NULL, ldb_module_operr(ar->module));
			}
		}
		if (!ldb_dn_add_base(msg->dn, parent_dn)) {
			talloc_free(ares);
			return ldb_module_done(ar->req, NULL, NULL, ldb_module_operr(ar->module));
		}
		break;
	}
	case LDB_REPLY_REFERRAL:
		 
		break;

	case LDB_REPLY_DONE:

		if (ar->objs->objects[ar->index_current].local_parent_dn == NULL) {
			struct GUID_txt_buf str_buf;
			if (ar->search_msg != NULL) {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "No parent with GUID %s found for object locally known as %s",
						       GUID_buf_string(ar->objs->objects[ar->index_current].parent_guid, &str_buf),
						       ldb_dn_get_linearized(ar->search_msg->dn));
			} else {
				ldb_asprintf_errstring(ldb_module_get_ctx(ar->module),
						       "No parent with GUID %s found for object remotely known as %s",
						       GUID_buf_string(ar->objs->objects[ar->index_current].parent_guid, &str_buf),
						       ldb_dn_get_linearized(ar->objs->objects[ar->index_current].msg->dn));
			}

			 
			return ldb_module_done(ar->req, NULL, NULL,
					       replmd_replicated_request_werror(ar, WERR_DS_DRA_MISSING_PARENT));
		}

		if (ar->search_msg != NULL) {
			ret = replmd_replicated_apply_merge(ar);
		} else {
			ret = replmd_replicated_apply_add(ar);
		}
		if (ret != LDB_SUCCESS) {
			return ldb_module_done(ar->req, NULL, NULL, ret);
		}
	}

	talloc_free(ares);
	return LDB_SUCCESS;
}