static int tombstone_reanimate_modify(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	const struct ldb_message_element *el_dn = NULL;
	struct tr_context *ac = NULL;
	int ret;

	ldb_debug(ldb, LDB_DEBUG_TRACE, "%s\n", __PRETTY_FUNCTION__);

	/* do not manipulate our control entries */
	if (ldb_dn_is_special(req->op.mod.message->dn)) {
		return ldb_next_request(module, req);
	}

	/* Check if this is a reanimate request */
	if (!is_tombstone_reanimate_request(req, &el_dn)) {
		return ldb_next_request(module, req);
	}

	ac = tr_init_context(module, req);
	if (ac == NULL) {
		return ldb_operr(ldb);
	}

	/* Load original object */
	ret = dsdb_module_search_dn(module, ac, &ac->search_res,
				    ac->req_msg->dn, NULL,
				    DSDB_FLAG_TOP_MODULE |
				    DSDB_SEARCH_SHOW_DELETED,
				    req);
	if (ret != LDB_SUCCESS) {
		return ldb_operr(ldb);
	}
	ac->search_msg = ac->search_res->msgs[0];

	/* check if it a Deleted Object */
	if (!ldb_msg_find_attr_as_bool(ac->search_msg, "isDeleted", false)) {
		return ldb_error(ldb, LDB_ERR_UNWILLING_TO_PERFORM, "Trying to restore not deleted object\n");
	}

	/* Simple implementation */

	/* prepare attributed depending on objectClass */
	ret = tr_prepare_attributes(ac);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	/* Rename request to modify distinguishedName */
	ret = tr_prepare_rename(ac, el_dn);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	/* restore attributed depending on objectClass */
	ret = tr_do_down_req(ac, ac->mod_req);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	/* Rename request to modify distinguishedName */
	ret = tr_do_down_req(ac, ac->rename_req);
	if (ret != LDB_SUCCESS) {
		ldb_debug(ldb, LDB_DEBUG_ERROR, "Renaming object to %s has failed with %s\n", el_dn->values[0].data, ldb_strerror(ret));
		if (ret != LDB_ERR_ENTRY_ALREADY_EXISTS && ret != LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS ) {
			/* Windows returns Operations Error in case we can't rename the object */
			return LDB_ERR_OPERATIONS_ERROR;
		}
		return ret;
	}

	return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
}
static int tombstone_reanimate_modify(struct ldb_module *module, struct ldb_request *req)
{
	struct ldb_context *ldb = ldb_module_get_ctx(module);
	const struct ldb_message_element *el_dn = NULL;
	struct tr_context *ac = NULL;
	int ret;

	ldb_debug(ldb, LDB_DEBUG_TRACE, "%s\n", __PRETTY_FUNCTION__);

	 
	if (ldb_dn_is_special(req->op.mod.message->dn)) {
		return ldb_next_request(module, req);
	}

	 
	if (!is_tombstone_reanimate_request(req, &el_dn)) {
		return ldb_next_request(module, req);
	}

	ac = tr_init_context(module, req);
	if (ac == NULL) {
		return ldb_operr(ldb);
	}

	 
	ret = dsdb_module_search_dn(module, ac, &ac->search_res,
				    ac->req_msg->dn, NULL,
				    DSDB_FLAG_TOP_MODULE |
				    DSDB_SEARCH_SHOW_DELETED,
				    req);
	if (ret != LDB_SUCCESS) {
		return ldb_operr(ldb);
	}
	ac->search_msg = ac->search_res->msgs[0];

	 
	if (!ldb_msg_find_attr_as_bool(ac->search_msg, "isDeleted", false)) {
		return ldb_error(ldb, LDB_ERR_UNWILLING_TO_PERFORM, "Trying to restore not deleted object\n");
	}

	 

	 
	ret = tr_prepare_attributes(ac);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	 
	ret = tr_prepare_rename(ac, el_dn);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	 
	ret = tr_do_down_req(ac, ac->mod_req);
	if (ret != LDB_SUCCESS) {
		return ret;
	}

	 
	ret = tr_do_down_req(ac, ac->rename_req);
	if (ret != LDB_SUCCESS) {
		ldb_debug(ldb, LDB_DEBUG_ERROR, "Renaming object to %s has failed with %s\n", el_dn->values[0].data, ldb_strerror(ret));
		if (ret != LDB_ERR_ENTRY_ALREADY_EXISTS && ret != LDB_ERR_INSUFFICIENT_ACCESS_RIGHTS ) {
			 
			return LDB_ERR_OPERATIONS_ERROR;
		}
		return ret;
	}

	return ldb_module_done(ac->req, NULL, NULL, LDB_SUCCESS);
}