From fae50d629a0db613613dc93e298401170eea6810 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Aug 01 2011 16:44:45 +0000 Subject: Bug 663752 - Cert renewal for attrcrypt and encchangelog https://bugzilla.redhat.com/show_bug.cgi?id=663752 Description: Replica config modify callback replica_config_post_ modify (repl5_replica_config.c) calls an internal modify API with s_configLock held. The modify ends up calling a replica config callback, in which it tries to acquire the same s_configLock and it hangs there since the locking function PR_Lock is not re-entrant. This patch avoids calling the internal modify API inside of s_configLock. (cherry picked from commit a5fdcddd4acc0811faa4a0152218a9702c979115) --- diff --git a/ldap/servers/plugins/replication/repl5_replica_config.c b/ldap/servers/plugins/replication/repl5_replica_config.c index 2caa94f..e31078f 100644 --- a/ldap/servers/plugins/replication/repl5_replica_config.c +++ b/ldap/servers/plugins/replication/repl5_replica_config.c @@ -79,6 +79,11 @@ static int replica_task_done(Replica *replica); static multimaster_mtnode_extension * _replica_config_get_mtnode_ext (const Slapi_Entry *e); +/* + * Note: internal add/modify/delete operations should not be run while + * s_configLock is held. E.g., slapi_modify_internal_pb via replica_task_done + * in replica_config_post_modify. + */ static PRLock *s_configLock; static int @@ -480,6 +485,7 @@ replica_config_post_modify(Slapi_PBlock *pb, char *config_attr, *config_attr_value; Slapi_Operation *op; void *identity; + int flag_need_cleanup = 0; if (returntext) { @@ -569,23 +575,29 @@ replica_config_post_modify(Slapi_PBlock *pb, if (strcasecmp (config_attr, TASK_ATTR) == 0) { - *returncode = replica_cleanup_task(mtnode_ext->replica, - config_attr_value, - errortext, apply_mods); + flag_need_cleanup = 1; } } } } done: - if (mtnode_ext->replica) - object_release (mtnode_ext->replica); - + PR_Unlock (s_configLock); + /* slapi_ch_free accepts NULL pointer */ - slapi_ch_free ((void**)&replica_root); + slapi_ch_free_string (&replica_root); - PR_Unlock (s_configLock); + /* Call replica_cleanup_task after s_configLock is reliesed */ + if (flag_need_cleanup) + { + *returncode = replica_cleanup_task(mtnode_ext->replica, + config_attr_value, + errortext, apply_mods); + } + if (mtnode_ext->replica) + object_release (mtnode_ext->replica); + if (*returncode != LDAP_SUCCESS) { return SLAPI_DSE_CALLBACK_ERROR;