ldap/servers/plugins/mep/mep.c | 40 +++++++++++++++++++++++++------- ldap/servers/slapd/plugin_internal_op.c | 17 +++++++++---- 2 files changed, 44 insertions(+), 13 deletions(-)
New commits: commit 379c164d5321549a249dc0a2f2ed7d79989801a0 Author: Nathan Kinder nkinder@redhat.com Date: Tue Sep 6 11:08:40 2011 -0700
Bug 735114 - renaming a managed entry does not update mepmanagedby
When a number of different plug-ins are being used that perform internal operations to update entries, it is possible for the managed entry plug-in to fail to update the managed entry. In particular, it has been found that renaming an origin entry can trigger a plug-in other than the managed entry plug-in to rename the managed entry. This causes the managed entry plug-in to fail when it attempts to update the managed entry.
This patch makes the managed entry plug-in check if the managed entry has already been renamed when processing a MODRDN operation. If it detects that the managed entry has already been renamed, it will use the new DN to perform the managed entry updates.
diff --git a/ldap/servers/plugins/mep/mep.c b/ldap/servers/plugins/mep/mep.c index 5e3aa17..0241cd3 100644 --- a/ldap/servers/plugins/mep/mep.c +++ b/ldap/servers/plugins/mep/mep.c @@ -2378,6 +2378,7 @@ mep_modrdn_post_op(Slapi_PBlock *pb) Slapi_Entry *new_managed_entry = NULL; Slapi_DN *managed_sdn = NULL; Slapi_Mods *smods = NULL; + int free_managed_dn = 1;
mep_config_read_lock();
@@ -2450,6 +2451,31 @@ mep_modrdn_post_op(Slapi_PBlock *pb) mods[0] = &mod; mods[1] = 0;
+ /* Create a new managed entry to determine what changes + * we need to make to the existing managed entry. */ + new_managed_entry = mep_create_managed_entry(config, post_e); + if (new_managed_entry == NULL) { + slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM, + "mep_modrdn_post_op: Unable to create in-memory " + "managed entry from origin entry "%s".\n", new_dn); + goto bailmod; + } + + /* Check if the managed entry exists. It is possible that + * it has already been renamed by another plug-in. If it + * has already been renamed, we need to use the new DN to + * perform our updates. */ + managed_sdn = slapi_sdn_new_dn_byref(managed_dn); + + if (slapi_search_internal_get_entry(managed_sdn, 0, + NULL, mep_get_plugin_id()) == LDAP_NO_SUCH_OBJECT) { + slapi_ch_free_string(&managed_dn); + /* This DN is not a copy, so we don't want to free it later. */ + managed_dn = slapi_entry_get_dn(new_managed_entry); + slapi_sdn_set_dn_byref(managed_sdn, managed_dn); + free_managed_dn = 0; + } + /* Perform the modify operation. */ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM, "mep_modrdn_post_op: Updating %s pointer to "%s" " @@ -2465,12 +2491,7 @@ mep_modrdn_post_op(Slapi_PBlock *pb) "origin entry "%s" in managed entry "%s" " "(%s).\n", new_dn, managed_dn, ldap_err2string(result)); } else { - /* Create a new managed entry to determine what changes - * we need to make to the existing managed entry. */ - new_managed_entry = mep_create_managed_entry(config, post_e); - /* See if we need to rename the managed entry. */ - managed_sdn = slapi_sdn_new_dn_byref(managed_dn); if (slapi_sdn_compare(slapi_entry_get_sdn(new_managed_entry), managed_sdn) != 0) { /* Rename the managed entry. */ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM, @@ -2510,14 +2531,17 @@ mep_modrdn_post_op(Slapi_PBlock *pb) slapi_mods_free(&smods); }
- slapi_sdn_free(&managed_sdn); - slapi_entry_free(new_managed_entry); } +bailmod: + slapi_entry_free(new_managed_entry); + slapi_sdn_free(&managed_sdn); }
slapi_pblock_destroy(mep_pb);
- slapi_ch_free_string(&managed_dn); + if (free_managed_dn) { + slapi_ch_free_string(&managed_dn); + }
mep_config_unlock(); } else { diff --git a/ldap/servers/slapd/plugin_internal_op.c b/ldap/servers/slapd/plugin_internal_op.c index 76f70e8..75d4e4a 100644 --- a/ldap/servers/slapd/plugin_internal_op.c +++ b/ldap/servers/slapd/plugin_internal_op.c @@ -872,7 +872,8 @@ void set_common_params (Slapi_PBlock *pb)
/* * Given a DN, find an entry by doing an internal search. An LDAP error - * code is returned. + * code is returned. To check if an entry exists without returning a + * copy of the entry, NULL can be passed for ret_entry. */ int slapi_search_internal_get_entry( Slapi_DN *dn, char ** attrs, Slapi_Entry **ret_entry , void * component_identity) @@ -881,7 +882,10 @@ slapi_search_internal_get_entry( Slapi_DN *dn, char ** attrs, Slapi_Entry **ret_ Slapi_PBlock *int_search_pb = NULL; int rc = 0;
- *ret_entry = NULL; + if (ret_entry) { + *ret_entry = NULL; + } + int_search_pb = slapi_pblock_new (); slapi_search_internal_set_pb ( int_search_pb, slapi_sdn_get_dn(dn), LDAP_SCOPE_BASE, "(|(objectclass=*)(objectclass=ldapsubentry))", attrs , @@ -893,9 +897,12 @@ slapi_search_internal_get_entry( Slapi_DN *dn, char ** attrs, Slapi_Entry **ret_ if ( LDAP_SUCCESS == rc ) { slapi_pblock_get( int_search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries ); if ( NULL != entries && NULL != entries[ 0 ]) { - Slapi_Entry *temp_entry = NULL; - temp_entry = entries[ 0 ]; - *ret_entry = slapi_entry_dup(temp_entry); + /* Only need to dup the entry if the caller passed ret_entry in. */ + if (ret_entry) { + Slapi_Entry *temp_entry = NULL; + temp_entry = entries[ 0 ]; + *ret_entry = slapi_entry_dup(temp_entry); + } } else { /* No entry there */ rc = LDAP_NO_SUCH_OBJECT;
389-commits@lists.fedoraproject.org