From 8f21ac81cfe8bf70b555ae011c9e7ff953deeb8e Mon Sep 17 00:00:00 2001
From: Mark Reynolds <mreynolds@redhat.com>
Date: Tue, 12 Jun 2012 16:32:32 -0400
Subject: [PATCH] Ticket #388 - Improve replication agreement status messages

Bug Description:  Result codes that were negative values triggered a generic error
                  message (System Error).  This is because of mozLDAP's ldap_err2string()
                  which can only handle positive values, but openldap's ldap_err2string
                  can handle both positive and negative numbers.

Fix Description:  Created a wrapper function (slapi_err2string), that can handle both
                  positive and negative error codes, regardless which ldap library is
                  being used.

Reviewed by:

https://fedorahosted.org/389/ticket/388
---
 ldap/servers/plugins/replication/repl5_agmt.c |   34 +++-----------
 ldap/servers/slapd/libglobs.c                 |   58 +++++++++++++++++++++++++
 ldap/servers/slapd/slapi-plugin.h             |    9 ++++
 3 files changed, 75 insertions(+), 26 deletions(-)

diff --git a/ldap/servers/plugins/replication/repl5_agmt.c b/ldap/servers/plugins/replication/repl5_agmt.c
index 4db7e13..4beb13a 100644
--- a/ldap/servers/plugins/replication/repl5_agmt.c
+++ b/ldap/servers/plugins/replication/repl5_agmt.c
@@ -2098,6 +2098,7 @@ agmt_set_last_update_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *
 		else if (ldaprc != LDAP_SUCCESS)
 		{
 			char *replmsg = NULL;
+
 			if ( replrc ) {
 				replmsg = protocol_response2string(replrc);
 				/* Do not mix the unknown replication error with the known ldap one */
@@ -2105,19 +2106,9 @@ agmt_set_last_update_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *
 					replmsg = NULL;
 				}
 			}
-			if (ldaprc > 0) {
-				PR_snprintf(ra->last_update_status, STATUS_LEN,
-							"%d %s%sLDAP error: %s%s%s",
-							ldaprc, 
-							message?message:"",message?"":" - ",
-							ldap_err2string(ldaprc),
-							replmsg ? " - " : "", replmsg ? replmsg : "");
-			} else { /* ldaprc is < 0 */
-				PR_snprintf(ra->last_update_status, STATUS_LEN,
-							"%d %s%sSystem error%s%s",
-							ldaprc,message?message:"",message?"":" - ",
-							replmsg ? " - " : "", replmsg ? replmsg : "");
-			}
+			PR_snprintf(ra->last_update_status, STATUS_LEN, "%d %s%sLDAP error: %s%s%s",
+				ldaprc, message?message:"",message?"":" - ",
+				slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "");
 		}
 		/* ldaprc == LDAP_SUCCESS */
 		else if (replrc != 0)
@@ -2175,6 +2166,7 @@ agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *me
 		if (ldaprc != LDAP_SUCCESS)
 		{
 			char *replmsg = NULL;
+
 			if ( replrc ) {
 				replmsg = protocol_response2string(replrc);
 				/* Do not mix the unknown replication error with the known ldap one */
@@ -2182,19 +2174,9 @@ agmt_set_last_init_status (Repl_Agmt *ra, int ldaprc, int replrc, const char *me
 					replmsg = NULL;
 				}
 			}
-			if (ldaprc > 0) {
-				PR_snprintf(ra->last_init_status, STATUS_LEN,
-							"%d %s%sLDAP error: %s%s%s",
-							ldaprc, 
-							message?message:"",message?"":" - ",
-							ldap_err2string(ldaprc),
-							replmsg ? " - " : "", replmsg ? replmsg : "");
-			} else { /* ldaprc is < 0 */
-				PR_snprintf(ra->last_init_status, STATUS_LEN,
-							"%d %s%sSystem error%s%s",
-							ldaprc,message?message:"",message?"":" - ",
-							replmsg ? " - " : "", replmsg ? replmsg : "");
-			}
+			PR_snprintf(ra->last_init_status, STATUS_LEN, "%d %s%sLDAP error: %s%s%s",
+				ldaprc, message?message:"",message?"":" - ",
+				slapi_err2string(ldaprc), replmsg ? " - " : "", replmsg ? replmsg : "");
 		}
 		/* ldaprc == LDAP_SUCCESS */
 		else if (replrc != 0)
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index c1e4051..282fc0d 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -6546,3 +6546,61 @@ config_set_auditlog_enabled(int value){
     }
     CFG_UNLOCK_WRITE(slapdFrontendConfig);
 }
+
+char *
+slapi_err2string(int result)
+{
+    /*
+     *  If we are using openldap, then we can safely use ldap_err2string with
+     *  positive and negative result codes.  MozLDAP's ldap_err2string can
+     *  only handle positive result codes.
+     */
+#if defined (USE_OPENLDAP)
+    return ldap_err2string(result);
+#else
+    if(result >= 0){
+        return ldap_err2string(result);
+    }
+    switch (result)
+    {
+        case -1:
+            return ("Can't contact LDAP server");
+        case -2:
+            return ("Local error");
+        case -3:
+            return ("Encoding error");
+        case -4:
+            return ("Decoding error");
+        case -5:
+            return ("Timed out");
+        case -6:
+            return ("Unknown authentication method");
+        case -7:
+            return ("Bad search filter");
+        case -8:
+            return ("User canceled operation");
+        case -9:
+            return ("Bad parameter to an ldap routine");
+        case -10:
+            return ("Out of memory");
+        case -11:
+            return ("Connect error");
+        case -12:
+            return ("Not Supported");
+        case -13:
+            return ("Control not found");
+        case -14:
+            return ("No results returned");
+        case -15:
+            return ("More results to return");
+        case -16:
+            return ("Client Loop");
+        case -17:
+            return ("Referral Limit Exceeded");
+
+        default:
+            return ("Unknown system error");
+    }
+#endif
+}
+
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index bad97f8..4dbf7db 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -5302,6 +5302,15 @@ void slapi_ch_array_add( char ***array, char *string );
 int slapi_ch_array_utf8_inlist(char **array, char *string);
 
 /**
+ * Returns the error string of an ldap result code, but it can also handle
+ * library errors(negative result codes)
+ *
+ * \param result The result code
+ * \return The error text string of the result code
+ */
+char *slapi_err2string(int result);
+
+/**
  * Check if the server has started shutting down
  *
  * \return 1 if the server is shutting down
-- 
1.7.1

