Sfoglia il codice sorgente

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.
Nathan Kinder 14 anni fa
parent
commit
379c164d53
2 ha cambiato i file con 44 aggiunte e 13 eliminazioni
  1. 32 8
      ldap/servers/plugins/mep/mep.c
  2. 12 5
      ldap/servers/slapd/plugin_internal_op.c

+ 32 - 8
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 {

+ 12 - 5
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;