From 1dfadfc65b607f8db54769e0c9147b499ce7efc2 Mon Sep 17 00:00:00 2001 From: Simon Pichugin Date: Jul 29 2020 15:13:51 +0000 Subject: Issue 51222 - It should not be allowed to delete Managed Entry manually Bug Description: It is possible to delete a managed entry and no error is raised. Also, while doing delete or modrdn peration on a managing entry and the managed entry doesn't exist, we should continue the operation. Fix Description: We should put an entry struct duplicate to SLAPI_ENTRY_PRE_OP pblock before we execute plugins PRE_OP. Also, we should allow to continue modrdn and delete managing entry operations execution even when managed entry doesn't exists. Allow 'cn=directory manager' to delete managed entry on direct update. https://pagure.io/389-ds-base/issue/51222 Reviewed by: ? --- diff --git a/ldap/servers/plugins/mep/mep.c b/ldap/servers/plugins/mep/mep.c index 401d95e..fe56512 100644 --- a/ldap/servers/plugins/mep/mep.c +++ b/ldap/servers/plugins/mep/mep.c @@ -2158,6 +2158,7 @@ mep_pre_op(Slapi_PBlock *pb, int modop) Slapi_Mod *next_mod = NULL; char *origin_dn = NULL; Slapi_DN *origin_sdn = NULL; + char *requestor_dn; /* Fetch the target entry. */ if (sdn) { @@ -2249,11 +2250,19 @@ mep_pre_op(Slapi_PBlock *pb, int modop) slapi_ch_free_string(&origin_dn); } else { - errstr = slapi_ch_smprintf("%s a managed entry is not allowed. " - "It needs to be manually unlinked first.", - modop == LDAP_CHANGETYPE_DELETE ? "Deleting" - : "Renaming"); - ret = LDAP_UNWILLING_TO_PERFORM; + slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &requestor_dn); + if (slapi_dn_isroot(requestor_dn)) { + slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM, + "mep_pre_op - %s is %s a managed entry.", + requestor_dn, modop == LDAP_CHANGETYPE_DELETE ? "deleting" + : "renaming"); + } else { + errstr = slapi_ch_smprintf("%s a managed entry is not allowed. " + "It needs to be manually unlinked first.", + modop == LDAP_CHANGETYPE_DELETE ? "Deleting" + : "Renaming"); + ret = LDAP_UNWILLING_TO_PERFORM; + } } } } @@ -2587,10 +2596,18 @@ mep_del_post_op(Slapi_PBlock *pb) slapi_delete_internal_pb(mep_pb); slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result); if (result) { - slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM, - "mep_del_post_op - Failed to delete managed entry " - "(%s) - error (%d)\n", - managed_dn, result); + if (result == LDAP_NO_SUCH_OBJECT) { + slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM, + "mep_del_post_op - Failed to delete managed entry " + "(%s) - it doesn't exist already)\n", + managed_dn); + result = SLAPI_PLUGIN_SUCCESS; + } else { + slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM, + "mep_del_post_op - Failed to delete managed entry " + "(%s) - error (%d)\n", + managed_dn, result); + } } slapi_ch_free_string(&managed_dn); slapi_pblock_destroy(mep_pb); @@ -2702,11 +2719,19 @@ mep_modrdn_post_op(Slapi_PBlock *pb) slapi_delete_internal_pb(mep_pb); slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result); if (result) { - slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM, - "mep_modrdn_post_op - Failed to delete managed entry " - "(%s) - error (%d)\n", - managed_dn, result); - goto bailmod; + if (result == LDAP_NO_SUCH_OBJECT) { + slapi_log_err(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM, + "mep_modrdn_post_op - Failed to delete managed entry " + "(%s) - it doesn't exist already)\n", + managed_dn); + result = SLAPI_PLUGIN_SUCCESS; + } else { + slapi_log_err(SLAPI_LOG_ERR, MEP_PLUGIN_SUBSYSTEM, + "mep_modrdn_post_op - Failed to delete managed entry " + "(%s) - error (%d)\n", + managed_dn, result); + goto bailmod; + } } /* Clear out the pblock for reuse. */ slapi_pblock_init(mep_pb); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c index 3b7a321..f509196 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c @@ -404,6 +404,9 @@ replace_entry: delete_tombstone_entry = operation_is_flag_set(operation, OP_FLAG_TOMBSTONE_ENTRY); } + /* Save away a copy of the entry, before modifications */ + slapi_pblock_set(pb, SLAPI_ENTRY_PRE_OP, slapi_entry_dup(e->ep_entry)); + /* call the transaction pre delete plugins just after the * to-be-deleted entry is prepared. */ /* these should not need to modify the entry to be deleted - @@ -500,8 +503,6 @@ replace_entry: "entry: %s - flags: delete %d is_tombstone_entry %d create %d \n", dn, delete_tombstone_entry, is_tombstone_entry, create_tombstone_entry); #endif - /* Save away a copy of the entry, before modifications */ - slapi_pblock_set(pb, SLAPI_ENTRY_PRE_OP, slapi_entry_dup(e->ep_entry)); /* * Get the entry's parent. We do this here because index_read