ldap/servers/plugins/replication/repl5_inc_protocol.c | 44 +++++++++++++++---
1 file changed, 38 insertions(+), 6 deletions(-)
New commits:
commit 72401ea2588d3aec7622155fdf5dd9e5af7f8f95
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Thu Mar 8 12:06:37 2012 -0700
Bug 800173 - RHDS fractional replication with excluded password policy attributes
leads to wrong error messages.
https://bugzilla.redhat.com/show_bug.cgi?id=800173
Resolves: Bug 800173
Bug Description: RHDS fractional replication with excluded password policy attributes
leads to wrong error messages.
Reviewed by: nhosoi (Thanks!)
Branch: Directory_Server_8_2_Branch
Fix Description: Fractional replication can remove _all_ mods in an add or
modify operation. The mozldap SDK will return an err=89 LDAP_PARAM_ERROR
in this case. The solution is to just skip add and modify operations
that contain no data.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/plugins/replication/repl5_inc_protocol.c
b/ldap/servers/plugins/replication/repl5_inc_protocol.c
index 4de9fc7..9279506 100644
--- a/ldap/servers/plugins/replication/repl5_inc_protocol.c
+++ b/ldap/servers/plugins/replication/repl5_inc_protocol.c
@@ -158,6 +158,9 @@ typedef struct result_data
*/
#define PROTOCOL_IS_SHUTDOWN(prp) (event_occurred(prp, EVENT_PROTOCOL_SHUTDOWN) ||
prp->terminate)
+/* mods should be LDAPMod **mods */
+#define MODS_ARE_EMPTY(mods) ((mods == NULL) || (mods[0] == NULL))
+
/* Forward declarations */
static PRUint32 event_occurred(Private_Repl_Protocol *prp, PRUint32 event);
static void reset_events (Private_Repl_Protocol *prp);
@@ -1389,6 +1392,11 @@ replay_update(Private_Repl_Protocol *prp,
slapi_operation_parameters *op, int *m
char csn_str[CSN_STRSIZE]; /* For logging only */
csn_as_string(op->csn, PR_FALSE, csn_str);
+ if (message_id) {
+ /* if we get out of this function without setting message_id, it means
+ we didn't send an op, so no result needs to be processed */
+ *message_id = 0;
+ }
/* Construct the replication info control that accompanies the operation */
if (SLAPI_OPERATION_ADD == op->operation_type)
@@ -1447,8 +1455,17 @@ replay_update(Private_Repl_Protocol *prp,
slapi_operation_parameters *op, int *m
{
repl5_strip_fractional_mods(prp->agmt,entryattrs);
}
- return_value = conn_send_add(prp->conn, op->target_address.dn,
- entryattrs, update_control, message_id);
+ if (MODS_ARE_EMPTY(entryattrs)) {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: replay_update: %s operation (dn=\"%s\" csn=%s) "
+ "not sent - empty\n",
+ agmt_get_long_name(prp->agmt),
+ op2string(op->operation_type), op->target_address.dn, csn_str);
+ return_value = CONN_OPERATION_SUCCESS;
+ } else {
+ return_value = conn_send_add(prp->conn, op->target_address.dn,
+ entryattrs, update_control, message_id);
+ }
ldap_mods_free(entryattrs, 1);
}
break;
@@ -1459,8 +1476,17 @@ replay_update(Private_Repl_Protocol *prp,
slapi_operation_parameters *op, int *m
{
repl5_strip_fractional_mods(prp->agmt,op->p.p_modify.modify_mods);
}
- return_value = conn_send_modify(prp->conn, op->target_address.dn,
- op->p.p_modify.modify_mods, update_control, message_id);
+ if (MODS_ARE_EMPTY(op->p.p_modify.modify_mods)) {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: replay_update: %ss operation (dn=\"%s\" csn=%s) "
+ "not sent - empty\n",
+ agmt_get_long_name(prp->agmt),
+ op2string(op->operation_type), op->target_address.dn, csn_str);
+ return_value = CONN_OPERATION_SUCCESS;
+ } else {
+ return_value = conn_send_modify(prp->conn, op->target_address.dn,
+ op->p.p_modify.modify_mods, update_control, message_id);
+ }
break;
case SLAPI_OPERATION_DELETE:
return_value = conn_send_delete(prp->conn, op->target_address.dn,
@@ -1867,7 +1893,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector,
PRUint32 *nu
replica_id = csn_get_replicaid(entry.op->csn);
uniqueid = entry.op->target_address.uniqueid;
- if (prp->repl50consumer)
+ if (prp->repl50consumer && message_id)
{
int operation, error = 0;
@@ -1879,7 +1905,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector,
PRUint32 *nu
csn_as_string(entry.op->csn, PR_FALSE, csn_str);
return_value = repl5_inc_update_from_op_result(prp, replay_crc, error, csn_str,
uniqueid, replica_id, &finished, num_changes_sent);
}
- else {
+ else if (message_id) {
/* Queue the details for pickup later in the response thread */
repl5_inc_operation *sop = NULL;
sop = repl5_inc_operation_new();
@@ -1889,6 +1915,12 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector,
PRUint32 *nu
sop->replica_id = replica_id;
sop->uniqueid = slapi_ch_strdup(uniqueid);
repl5_int_push_operation(rd,sop);
+ } else {
+ slapi_log_error(SLAPI_LOG_REPL, repl_plugin_name,
+ "%s: Skipping update operation with no message_id (uniqueid %s, CSN
%s):\n",
+ agmt_get_long_name(prp->agmt),
+ entry.op->target_address.uniqueid, csn_str);
+ agmt_inc_last_update_changecount (prp->agmt,
csn_get_replicaid(entry.op->csn), 1 /*skipped*/);
}
}
break;