summaryrefslogtreecommitdiffstats
path: root/ldap/servers
diff options
context:
space:
mode:
authorDavid Boreham <dboreham@redhat.com>2005-04-28 22:50:15 +0000
committerDavid Boreham <dboreham@redhat.com>2005-04-28 22:50:15 +0000
commit7cf67d15b3c96b1fad71e20036552de08527e276 (patch)
treeee77212f8d285b76aa63a6e8c2bce004e8287d17 /ldap/servers
parent984a784f2c0d1c9115baee85b967f010285830a1 (diff)
downloadds-7cf67d15b3c96b1fad71e20036552de08527e276.tar.gz
ds-7cf67d15b3c96b1fad71e20036552de08527e276.tar.xz
ds-7cf67d15b3c96b1fad71e20036552de08527e276.zip
Fix the fact that if an operation fails in a total update, we immediately halt
Diffstat (limited to 'ldap/servers')
-rw-r--r--ldap/servers/plugins/replication/windows_inc_protocol.c98
-rw-r--r--ldap/servers/plugins/replication/windows_prot_private.h2
-rw-r--r--ldap/servers/plugins/replication/windows_protocol_util.c128
3 files changed, 127 insertions, 101 deletions
diff --git a/ldap/servers/plugins/replication/windows_inc_protocol.c b/ldap/servers/plugins/replication/windows_inc_protocol.c
index cb9e9c0e..b5325b92 100644
--- a/ldap/servers/plugins/replication/windows_inc_protocol.c
+++ b/ldap/servers/plugins/replication/windows_inc_protocol.c
@@ -142,7 +142,6 @@ static void protocol_sleep(Private_Repl_Protocol *prp, PRIntervalTime duration);
static int send_updates(Private_Repl_Protocol *prp, RUV *ruv, PRUint32 *num_changes_sent);
static void windows_inc_backoff_expired(time_t timer_fire_time, void *arg);
static int windows_examine_update_vector(Private_Repl_Protocol *prp, RUV *ruv);
-static PRBool ignore_error_and_keep_going(int error);
static const char* state2name (int state);
static const char* event2name (int event);
static const char* acquire2name (int code);
@@ -1271,7 +1270,7 @@ send_updates(Private_Repl_Protocol *prp, RUV *remote_update_vector, PRUint32 *nu
if (CONN_OPERATION_FAILED == replay_crc)
{
/* Map ldap error code to return value */
- if (!ignore_error_and_keep_going(error))
+ if (!windows_ignore_error_and_keep_going(error))
{
return_value = UPDATE_TRANSIENT_ERROR;
finished = 1;
@@ -1643,101 +1642,6 @@ windows_examine_update_vector(Private_Repl_Protocol *prp, RUV *remote_ruv)
}
-/*
- * When we get an error from an LDAP operation, we call this
- * function to decide if we should just keep replaying
- * updates, or if we should stop, back off, and try again
- * later.
- * Returns PR_TRUE if we shoould keep going, PR_FALSE if
- * we should back off and try again later.
- *
- * In general, we keep going if the return code is consistent
- * with some sort of bug in URP that causes the consumer to
- * emit an error code that it shouldn't have, e.g. LDAP_ALREADY_EXISTS.
- *
- * We stop if there's some indication that the server just completely
- * failed to process the operation, e.g. LDAP_OPERATIONS_ERROR.
- */
-static PRBool
-ignore_error_and_keep_going(int error)
-{
- int return_value;
-
- LDAPDebug( LDAP_DEBUG_TRACE, "=> ignore_error_and_keep_going\n", 0, 0, 0 );
-
- switch (error)
- {
- /* Cases where we keep going */
- case LDAP_SUCCESS:
- case LDAP_NO_SUCH_ATTRIBUTE:
- case LDAP_UNDEFINED_TYPE:
- case LDAP_CONSTRAINT_VIOLATION:
- case LDAP_TYPE_OR_VALUE_EXISTS:
- case LDAP_INVALID_SYNTAX:
- case LDAP_NO_SUCH_OBJECT:
- case LDAP_INVALID_DN_SYNTAX:
- case LDAP_IS_LEAF:
- case LDAP_INSUFFICIENT_ACCESS:
- case LDAP_NAMING_VIOLATION:
- case LDAP_OBJECT_CLASS_VIOLATION:
- case LDAP_NOT_ALLOWED_ON_NONLEAF:
- case LDAP_NOT_ALLOWED_ON_RDN:
- case LDAP_ALREADY_EXISTS:
- case LDAP_NO_OBJECT_CLASS_MODS:
- return_value = PR_TRUE;
- break;
-
- /* Cases where we stop and retry */
- case LDAP_OPERATIONS_ERROR:
- case LDAP_PROTOCOL_ERROR:
- case LDAP_TIMELIMIT_EXCEEDED:
- case LDAP_SIZELIMIT_EXCEEDED:
- case LDAP_STRONG_AUTH_NOT_SUPPORTED:
- case LDAP_STRONG_AUTH_REQUIRED:
- case LDAP_PARTIAL_RESULTS:
- case LDAP_REFERRAL:
- case LDAP_ADMINLIMIT_EXCEEDED:
- case LDAP_UNAVAILABLE_CRITICAL_EXTENSION:
- case LDAP_CONFIDENTIALITY_REQUIRED:
- case LDAP_SASL_BIND_IN_PROGRESS:
- case LDAP_INAPPROPRIATE_MATCHING:
- case LDAP_ALIAS_PROBLEM:
- case LDAP_ALIAS_DEREF_PROBLEM:
- case LDAP_INAPPROPRIATE_AUTH:
- case LDAP_INVALID_CREDENTIALS:
- case LDAP_BUSY:
- case LDAP_UNAVAILABLE:
- case LDAP_UNWILLING_TO_PERFORM:
- case LDAP_LOOP_DETECT:
- case LDAP_SORT_CONTROL_MISSING:
- case LDAP_INDEX_RANGE_ERROR:
- case LDAP_RESULTS_TOO_LARGE:
- case LDAP_AFFECTS_MULTIPLE_DSAS:
- case LDAP_OTHER:
- case LDAP_SERVER_DOWN:
- case LDAP_LOCAL_ERROR:
- case LDAP_ENCODING_ERROR:
- case LDAP_DECODING_ERROR:
- case LDAP_TIMEOUT:
- case LDAP_AUTH_UNKNOWN:
- case LDAP_FILTER_ERROR:
- case LDAP_USER_CANCELLED:
- case LDAP_PARAM_ERROR:
- case LDAP_NO_MEMORY:
- case LDAP_CONNECT_ERROR:
- case LDAP_NOT_SUPPORTED:
- case LDAP_CONTROL_NOT_FOUND:
- case LDAP_NO_RESULTS_RETURNED:
- case LDAP_MORE_RESULTS_TO_RETURN:
- case LDAP_CLIENT_LOOP:
- case LDAP_REFERRAL_LIMIT_EXCEEDED:
- return_value = PR_FALSE;
- break;
- }
- LDAPDebug( LDAP_DEBUG_TRACE, "<= ignore_error_and_keep_going\n", 0, 0, 0 );
- return return_value;
-}
-
/* this function converts an aquisition code to a string - for debug output */
static const char*
acquire2name (int code)
diff --git a/ldap/servers/plugins/replication/windows_prot_private.h b/ldap/servers/plugins/replication/windows_prot_private.h
index 772aa792..c01e8cb0 100644
--- a/ldap/servers/plugins/replication/windows_prot_private.h
+++ b/ldap/servers/plugins/replication/windows_prot_private.h
@@ -101,4 +101,6 @@ void windows_dirsync_inc_run(Private_Repl_Protocol *prp);
ConnResult windows_replay_update(Private_Repl_Protocol *prp, slapi_operation_parameters *op);
int windows_process_total_entry(Private_Repl_Protocol *prp,Slapi_Entry *e);
+PRBool windows_ignore_error_and_keep_going(int error);
+
#endif /* _REPL5_PROT_PRIVATE_H_ */
diff --git a/ldap/servers/plugins/replication/windows_protocol_util.c b/ldap/servers/plugins/replication/windows_protocol_util.c
index 8c06d1aa..b942fcb4 100644
--- a/ldap/servers/plugins/replication/windows_protocol_util.c
+++ b/ldap/servers/plugins/replication/windows_protocol_util.c
@@ -197,7 +197,7 @@ static windows_attribute_map user_attribute_map[] =
{ "streetAddress", "street", towindowsonly, always, normal},
{ "userParameters", "ntUserParms", bidirectional, always, normal},
{ "userWorkstations", "ntUserWorkstations", bidirectional, always, normal},
- { "sAMAccountName", "ntUserDomainId", bidirectional, createonly, normal},
+ { "sAMAccountName", "ntUserDomainId", bidirectional, always, normal},
/* cn is a naming attribute in AD, so we don't want to change it after entry creation */
{ "cn", "cn", towindowsonly, createonly, normal},
/* However, it isn't a naming attribute in DS (we use uid) so it's safe to accept changes inbound */
@@ -231,6 +231,101 @@ static windows_attribute_map group_attribute_map[] =
* 6. NT4 has less and different schema from AD. For example users in NT4 have no firstname/lastname, only an optional 'description'.
*/
+/*
+ * When we get an error from an LDAP operation, we call this
+ * function to decide if we should just keep replaying
+ * updates, or if we should stop, back off, and try again
+ * later.
+ * Returns PR_TRUE if we shoould keep going, PR_FALSE if
+ * we should back off and try again later.
+ *
+ * In general, we keep going if the return code is consistent
+ * with some sort of bug in URP that causes the consumer to
+ * emit an error code that it shouldn't have, e.g. LDAP_ALREADY_EXISTS.
+ *
+ * We stop if there's some indication that the server just completely
+ * failed to process the operation, e.g. LDAP_OPERATIONS_ERROR.
+ */
+PRBool
+windows_ignore_error_and_keep_going(int error)
+{
+ int return_value;
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_ignore_error_and_keep_going\n", 0, 0, 0 );
+
+ switch (error)
+ {
+ /* Cases where we keep going */
+ case LDAP_SUCCESS:
+ case LDAP_NO_SUCH_ATTRIBUTE:
+ case LDAP_UNDEFINED_TYPE:
+ case LDAP_CONSTRAINT_VIOLATION:
+ case LDAP_TYPE_OR_VALUE_EXISTS:
+ case LDAP_INVALID_SYNTAX:
+ case LDAP_NO_SUCH_OBJECT:
+ case LDAP_INVALID_DN_SYNTAX:
+ case LDAP_IS_LEAF:
+ case LDAP_INSUFFICIENT_ACCESS:
+ case LDAP_NAMING_VIOLATION:
+ case LDAP_OBJECT_CLASS_VIOLATION:
+ case LDAP_NOT_ALLOWED_ON_NONLEAF:
+ case LDAP_NOT_ALLOWED_ON_RDN:
+ case LDAP_ALREADY_EXISTS:
+ case LDAP_NO_OBJECT_CLASS_MODS:
+ return_value = PR_TRUE;
+ break;
+
+ /* Cases where we stop and retry */
+ case LDAP_OPERATIONS_ERROR:
+ case LDAP_PROTOCOL_ERROR:
+ case LDAP_TIMELIMIT_EXCEEDED:
+ case LDAP_SIZELIMIT_EXCEEDED:
+ case LDAP_STRONG_AUTH_NOT_SUPPORTED:
+ case LDAP_STRONG_AUTH_REQUIRED:
+ case LDAP_PARTIAL_RESULTS:
+ case LDAP_REFERRAL:
+ case LDAP_ADMINLIMIT_EXCEEDED:
+ case LDAP_UNAVAILABLE_CRITICAL_EXTENSION:
+ case LDAP_CONFIDENTIALITY_REQUIRED:
+ case LDAP_SASL_BIND_IN_PROGRESS:
+ case LDAP_INAPPROPRIATE_MATCHING:
+ case LDAP_ALIAS_PROBLEM:
+ case LDAP_ALIAS_DEREF_PROBLEM:
+ case LDAP_INAPPROPRIATE_AUTH:
+ case LDAP_INVALID_CREDENTIALS:
+ case LDAP_BUSY:
+ case LDAP_UNAVAILABLE:
+ case LDAP_UNWILLING_TO_PERFORM:
+ case LDAP_LOOP_DETECT:
+ case LDAP_SORT_CONTROL_MISSING:
+ case LDAP_INDEX_RANGE_ERROR:
+ case LDAP_RESULTS_TOO_LARGE:
+ case LDAP_AFFECTS_MULTIPLE_DSAS:
+ case LDAP_OTHER:
+ case LDAP_SERVER_DOWN:
+ case LDAP_LOCAL_ERROR:
+ case LDAP_ENCODING_ERROR:
+ case LDAP_DECODING_ERROR:
+ case LDAP_TIMEOUT:
+ case LDAP_AUTH_UNKNOWN:
+ case LDAP_FILTER_ERROR:
+ case LDAP_USER_CANCELLED:
+ case LDAP_PARAM_ERROR:
+ case LDAP_NO_MEMORY:
+ case LDAP_CONNECT_ERROR:
+ case LDAP_NOT_SUPPORTED:
+ case LDAP_CONTROL_NOT_FOUND:
+ case LDAP_NO_RESULTS_RETURNED:
+ case LDAP_MORE_RESULTS_TO_RETURN:
+ case LDAP_CLIENT_LOOP:
+ case LDAP_REFERRAL_LIMIT_EXCEEDED:
+ return_value = PR_FALSE;
+ break;
+ }
+ LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_ignore_error_and_keep_going\n", 0, 0, 0 );
+ return return_value;
+}
+
static const char*
op2string(int op)
{
@@ -318,7 +413,13 @@ map_dn_values(Private_Repl_Protocol *prp,Slapi_ValueSet *original_values, Slapi_
}
}
slapi_sdn_free(&remote_dn);
+ } else
+ {
+ slapi_log_error(SLAPI_LOG_REPL, NULL, "map_dn_values: no remote dn found for %s\n", original_dn_string);
}
+ } else
+ {
+ slapi_log_error(SLAPI_LOG_REPL, NULL, "map_dn_values: this entry is not ours %s\n", original_dn_string);
}
} else {
slapi_log_error(SLAPI_LOG_REPL, NULL, "map_dn_values: no local entry found for %s\n", original_dn_string);
@@ -354,6 +455,9 @@ map_dn_values(Private_Repl_Protocol *prp,Slapi_ValueSet *original_values, Slapi_
{
slapi_log_error(SLAPI_LOG_REPL, NULL, "map_dn_values: no local dn found for %s\n", original_dn_string);
}
+ } else
+ {
+ slapi_log_error(SLAPI_LOG_REPL, NULL, "map_dn_values: this entry is not ours %s\n", original_dn_string);
}
} else
{
@@ -2316,7 +2420,7 @@ windows_generate_update_mods(Private_Repl_Protocol *prp,Slapi_Entry *remote_entr
int rc = 0;
int is_nt4 = windows_private_get_isnt4(prp->agmt);
/* Iterate over the attributes on the remote entry, updating the local entry where appropriate */
- LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_update_local_entry\n", 0, 0, 0 );
+ LDAPDebug( LDAP_DEBUG_TRACE, "=> windows_generate_update_mods\n", 0, 0, 0 );
*do_modify = 0;
if (to_windows)
@@ -2379,12 +2483,14 @@ windows_generate_update_mods(Private_Repl_Protocol *prp,Slapi_Entry *remote_entr
/* If it is then we need to replace the local values with the remote values if they are different */
if (!values_equal)
{
+ slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
+ "windows_generate_update_mods: %s, %s : values are different\n", slapi_sdn_get_dn(slapi_entry_get_sdn_const(local_entry)), local_type);
slapi_mods_add_mod_values(smods,LDAP_MOD_REPLACE,local_type,valueset_get_valuearray(vs));
*do_modify = 1;
} else
{
slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
- "windows_update_local_entry: %s, %s : values are equal\n", slapi_sdn_get_dn(slapi_entry_get_sdn_const(local_entry)), local_type);
+ "windows_generate_update_mods: %s, %s : values are equal\n", slapi_sdn_get_dn(slapi_entry_get_sdn_const(local_entry)), local_type);
}
} else {
/* A dn-valued attribute : need to take special steps */
@@ -2418,6 +2524,8 @@ windows_generate_update_mods(Private_Repl_Protocol *prp,Slapi_Entry *remote_entr
{
if (!is_present_local)
{
+ slapi_log_error(SLAPI_LOG_REPL, windows_repl_plugin_name,
+ "windows_generate_update_mods: %s, %s : values not present on peer entry\n", slapi_sdn_get_dn(slapi_entry_get_sdn_const(local_entry)), local_type);
/* If it is currently absent, then we add the value from the remote entry */
if (is_guid)
{
@@ -2464,7 +2572,7 @@ windows_generate_update_mods(Private_Repl_Protocol *prp,Slapi_Entry *remote_entr
{
slapi_mods_dump(smods,"windows sync");
}
- LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_update_local_entry: %d\n", retval, 0, 0 );
+ LDAPDebug( LDAP_DEBUG_TRACE, "<= windows_generate_update_mods: %d\n", retval, 0, 0 );
return retval;
}
@@ -2583,6 +2691,18 @@ windows_process_total_add(Private_Repl_Protocol *prp,Slapi_Entry *e, Slapi_DN* r
if (0 == retval && remote_entry)
{
retval = windows_update_remote_entry(prp,remote_entry,e);
+ /* Detect the case where the error is benign */
+ if (retval)
+ {
+ int operation = 0;
+ int error = 0;
+
+ conn_get_error(prp->conn, &operation, &error);
+ if (windows_ignore_error_and_keep_going(error))
+ {
+ retval = CONN_OPERATION_SUCCESS;
+ }
+ }
}
if (remote_entry)
{