Browse Source

Ticket 317 - RHDS fractional replication with excluded password policy attributes leads to wrong error messages.

https://fedorahosted.org/389/ticket/317
Resolves: Ticket 317
Bug Description: RHDS fractional replication with excluded password policy attributes leads to wrong error messages.
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description: Fractional replication can remove _all_ mods in an add or
modify operation. The code should just skip add and modify operations
that contain no data.
Platforms tested: RHEL6 x86_64
Flag Day: no
Doc impact: no
cherry picked and ported from 72401ea2588d3aec7622155fdf5dd9e5af7f8f95 on Directory_Server_8_2_Branch
Rich Megginson 13 năm trước cách đây
mục cha
commit
c72f6ba1e9
1 tập tin đã thay đổi với 47 bổ sung6 xóa
  1. 47 6
      ldap/servers/plugins/replication/repl5_inc_protocol.c

+ 47 - 6
ldap/servers/plugins/replication/repl5_inc_protocol.c

@@ -163,6 +163,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);
@@ -1385,6 +1388,12 @@ replay_update(Private_Repl_Protocol *prp, slapi_operation_parameters *op, int *m
 	LDAPMod **modrdn_mods = NULL;
 	char csn_str[CSN_STRSIZE]; /* For logging only */
 
+	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)
 	{
@@ -1445,8 +1454,21 @@ 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, REPL_GET_DN(&op->target_address),
-					entryattrs, update_control, message_id);
+				if (MODS_ARE_EMPTY(entryattrs)) {
+					if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+						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),
+										REPL_GET_DN(&op->target_address),
+										csn_as_string(op->csn, PR_FALSE, csn_str));
+					}
+					return_value = CONN_OPERATION_SUCCESS;
+				} else {
+					return_value = conn_send_add(prp->conn, REPL_GET_DN(&op->target_address),
+						entryattrs, update_control, message_id);
+				}
 				ldap_mods_free(entryattrs, 1);
 			}
 			break;
@@ -1457,8 +1479,21 @@ 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, REPL_GET_DN(&op->target_address),
-				op->p.p_modify.modify_mods, update_control, message_id);
+			if (MODS_ARE_EMPTY(op->p.p_modify.modify_mods)) {
+				if (slapi_is_loglevel_set(SLAPI_LOG_REPL)) {
+					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),
+									REPL_GET_DN(&op->target_address),
+									csn_as_string(op->csn, PR_FALSE, csn_str));
+				}
+				return_value = CONN_OPERATION_SUCCESS;
+			} else {
+				return_value = conn_send_modify(prp->conn, REPL_GET_DN(&op->target_address),
+					op->p.p_modify.modify_mods, update_control, message_id);
+			}
 			break;
 		case SLAPI_OPERATION_DELETE:
 			return_value = conn_send_delete(prp->conn, REPL_GET_DN(&op->target_address),
@@ -1869,7 +1904,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;
 
@@ -1881,7 +1916,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();
@@ -1891,6 +1926,12 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
 						sop->replica_id = replica_id;
 						PL_strncpyz(sop->uniqueid, uniqueid, sizeof(sop->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;