From d2308c8bbe8f0fe7d308d1c5fa1171a20e57b122 Mon Sep 17 00:00:00 2001
From: Quanah Gibson-Mount <quanah@openldap.org>
Date: Wed, 8 Jul 2009 02:28:21 +0000
Subject: [PATCH] ITS#5892

---
 CHANGES                         |  1 +
 clients/tools/ldapmodify.c      |  9 ++++++---
 libraries/liblutil/ldif.c       |  5 +++--
 servers/slapd/back-sql/config.c |  9 ++++++---
 servers/slapd/ldapsync.c        | 23 +++++++++++------------
 servers/slapd/root_dse.c        | 11 +++++++----
 servers/slapd/slapadd.c         |  7 +++++--
 servers/slapd/slapcommon.c      |  1 +
 8 files changed, 40 insertions(+), 26 deletions(-)

diff --git a/CHANGES b/CHANGES
index 332d713d76..1b2d783151 100644
--- a/CHANGES
+++ b/CHANGES
@@ -54,6 +54,7 @@ OpenLDAP 2.4.17 Engineering
 	Fixed slapo-rwm entry free (ITS#6058)
 	Fixed slapo-rwm entry release (ITS#6081)
 	Fixed slapo-translucent entry gathering (ITS#6156)
+	Fixed tools returning ldif errors (ITS#5892)
 	Fixed contrib/smbk5pwd use of private functions (ITS#5535)
 	Build Environment
 		Added test056-monitor (ITS#5540)
diff --git a/clients/tools/ldapmodify.c b/clients/tools/ldapmodify.c
index c119c5e9ee..277f11be2c 100644
--- a/clients/tools/ldapmodify.c
+++ b/clients/tools/ldapmodify.c
@@ -240,7 +240,7 @@ main( int argc, char **argv )
 	FILE		*rejfp;
 	struct LDIFFP *ldiffp, ldifdummy = {0};
 	char		*matched_msg, *error_msg;
-	int		rc, retval;
+	int		rc, retval, ldifrc;
 	int		len;
 	int		i = 0;
 	int		lineno, nextline = 0, lmax = 0;
@@ -326,8 +326,8 @@ main( int argc, char **argv )
 	rc = 0;
 	retval = 0;
 	lineno = 1;
-	while (( rc == 0 || contoper ) && ldif_read_record( ldiffp, &nextline,
-		&rbuf, &lmax ))
+	while (( rc == 0 || contoper ) && ( ldifrc = ldif_read_record( ldiffp, &nextline,
+		&rbuf, &lmax )) > 0 )
 	{
 		if ( rejfp ) {
 			len = strlen( rbuf );
@@ -369,6 +369,9 @@ main( int argc, char **argv )
 	}
 	ber_memfree( rbuf );
 
+	if ( ldifrc < 0 )
+		retval = LDAP_OTHER;
+
 #ifdef LDAP_X_TXN
 	if( retval == 0 && txn ) {
 		rc = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, NULL );
diff --git a/libraries/liblutil/ldif.c b/libraries/liblutil/ldif.c
index 2eb31ae258..0e56870737 100644
--- a/libraries/liblutil/ldif.c
+++ b/libraries/liblutil/ldif.c
@@ -780,7 +780,8 @@ ldif_close(
 #define	LDIF_MAXLINE	4096
 
 /*
- * ldif_read_record - read an ldif record.  Return 1 for success, 0 for EOF.
+ * ldif_read_record - read an ldif record.  Return 1 for success, 0 for EOF,
+ * -1 for error.
  */
 int
 ldif_read_record(
@@ -882,7 +883,7 @@ ldif_read_record(
 							 */
 							ber_pvt_log_printf( LDAP_DEBUG_ANY, ldif_debug,
 								_("ldif_read_record: include %s failed\n"), ptr );
-							return 0;
+							return -1;
 						}
 					}
 				}
diff --git a/servers/slapd/back-sql/config.c b/servers/slapd/back-sql/config.c
index fcf0d63e19..23f6525aa5 100644
--- a/servers/slapd/back-sql/config.c
+++ b/servers/slapd/back-sql/config.c
@@ -659,7 +659,7 @@ read_baseObject(
 {
 	backsql_info 	*bi = (backsql_info *)be->be_private;
 	LDIFFP		*fp;
-	int		rc = 0, lineno = 0, lmax = 0;
+	int		rc = 0, lineno = 0, lmax = 0, ldifrc;
 	char		*buf = NULL;
 
 	assert( fname != NULL );
@@ -685,7 +685,7 @@ read_baseObject(
 	bi->sql_baseObject->e_nname = be->be_nsuffix[0];
 	bi->sql_baseObject->e_attrs = NULL;
 
-	while ( ldif_read_record( fp, &lineno, &buf, &lmax ) ) {
+	while (( ldifrc = ldif_read_record( fp, &lineno, &buf, &lmax )) > 0 ) {
 		Entry		*e = str2entry( buf );
 		Attribute	*a;
 
@@ -704,7 +704,7 @@ read_baseObject(
 				"dn=\"%s\" (line=%d)\n",
 				e->e_name.bv_val, lineno );
 			entry_free( e );
-			rc = EXIT_FAILURE;
+			rc = LDAP_OTHER;
 			break;
 		}
 
@@ -729,6 +729,9 @@ read_baseObject(
 		}
 	}
 
+	if ( ldifrc < 0 )
+		rc = LDAP_OTHER;
+
 	if ( rc ) {
 		entry_free( bi->sql_baseObject );
 		bi->sql_baseObject = NULL;
diff --git a/servers/slapd/ldapsync.c b/servers/slapd/ldapsync.c
index f71bedaf45..0e08030119 100644
--- a/servers/slapd/ldapsync.c
+++ b/servers/slapd/ldapsync.c
@@ -176,7 +176,7 @@ slap_parse_sync_cookie(
 	char *csn_str;
 	char *cval;
 	char *next, *end;
-	AttributeDescription *ad = slap_schema.si_ad_modifyTimestamp;
+	AttributeDescription *ad = slap_schema.si_ad_entryCSN;
 
 	if ( cookie == NULL )
 		return -1;
@@ -230,13 +230,11 @@ slap_parse_sync_cookie(
 			continue;
 		}
 		if ( !strncmp( next, "csn=", STRLENOF("csn=") )) {
-			slap_syntax_validate_func *validate;
 			struct berval stamp;
 
 			next += STRLENOF("csn=");
 			while ( next < end ) {
 				csn_str = next;
-				/* FIXME use csnValidate when it gets implemented */
 				csn_ptr = strchr( csn_str, '#' );
 				if ( !csn_ptr || csn_ptr > end )
 					break;
@@ -244,14 +242,6 @@ slap_parse_sync_cookie(
 				 * want to parse the rid then. But we still iterate
 				 * through the string to find the end.
 				 */
-				if ( ad ) {
-					stamp.bv_val = csn_str;
-					stamp.bv_len = csn_ptr - csn_str;
-					validate = ad->ad_type->sat_syntax->ssyn_validate;
-					if ( validate( ad->ad_type->sat_syntax, &stamp )
-						!= LDAP_SUCCESS )
-						break;
-				}
 				cval = strchr( csn_ptr, ';' );
 				if ( !cval )
 					cval = strchr(csn_ptr, ',' );
@@ -261,7 +251,16 @@ slap_parse_sync_cookie(
 					stamp.bv_len = end - csn_str;
 				if ( ad ) {
 					struct berval bv;
-					ber_dupbv_x( &bv, &stamp, memctx );
+					stamp.bv_val = csn_str;
+					if ( ad->ad_type->sat_syntax->ssyn_validate(
+						ad->ad_type->sat_syntax, &stamp ) != LDAP_SUCCESS )
+						break;
+					if ( ad->ad_type->sat_equality->smr_normalize(
+						SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
+						ad->ad_type->sat_syntax,
+						ad->ad_type->sat_equality,
+						&stamp, &bv, memctx ) != LDAP_SUCCESS )
+						break;
 					ber_bvarray_add_x( &cookie->ctxcsn, &bv, memctx );
 					cookie->numcsns++;
 				}
diff --git a/servers/slapd/root_dse.c b/servers/slapd/root_dse.c
index 8b7322122e..3f1897bf10 100644
--- a/servers/slapd/root_dse.c
+++ b/servers/slapd/root_dse.c
@@ -401,7 +401,7 @@ int
 root_dse_read_file( const char *fname )
 {
 	struct LDIFFP	*fp;
-	int rc = 0, lineno = 0, lmax = 0;
+	int rc = 0, lineno = 0, lmax = 0, ldifrc;
 	char	*buf = NULL;
 
 	if ( (fp = ldif_open( fname, "r" )) == NULL ) {
@@ -421,7 +421,7 @@ root_dse_read_file( const char *fname )
 	}
 	usr_attr->e_attrs = NULL;
 
-	while( ldif_read_record( fp, &lineno, &buf, &lmax ) ) {
+	while(( ldifrc = ldif_read_record( fp, &lineno, &buf, &lmax )) > 0 ) {
 		Entry *e = str2entry( buf );
 		Attribute *a;
 
@@ -429,7 +429,7 @@ root_dse_read_file( const char *fname )
 			Debug( LDAP_DEBUG_ANY, "root_dse_read_file: "
 				"could not parse entry (file=\"%s\" line=%d)\n",
 				fname, lineno, 0 );
-			rc = EXIT_FAILURE;
+			rc = LDAP_OTHER;
 			break;
 		}
 
@@ -440,7 +440,7 @@ root_dse_read_file( const char *fname )
 				"- dn=\"%s\" (file=\"%s\" line=%d)\n",
 				e->e_dn, fname, lineno );
 			entry_free( e );
-			rc = EXIT_FAILURE;
+			rc = LDAP_OTHER;
 			break;
 		}
 
@@ -463,6 +463,9 @@ root_dse_read_file( const char *fname )
 		if (rc) break;
 	}
 
+	if ( ldifrc < 0 )
+		rc = LDAP_OTHER;
+
 	if (rc) {
 		entry_free( usr_attr );
 		usr_attr = NULL;
diff --git a/servers/slapd/slapadd.c b/servers/slapd/slapadd.c
index a6cf3a2e21..b08fd3cea2 100644
--- a/servers/slapd/slapadd.c
+++ b/servers/slapd/slapadd.c
@@ -64,7 +64,7 @@ slapadd( int argc, char **argv )
 
 	int match;
 	int checkvals;
-	int lineno, nextline;
+	int lineno, nextline, ldifrc;
 	int lmax;
 	int rc = EXIT_SUCCESS;
 	int manage = 0;	
@@ -142,7 +142,7 @@ slapadd( int argc, char **argv )
 	}
 
 	/* nextline is the line number of the end of the current entry */
-	for( lineno=1; ldif_read_record( ldiffp, &nextline, &buf, &lmax );
+	for( lineno=1; ( ldifrc = ldif_read_record( ldiffp, &nextline, &buf, &lmax )) > 0;
 		lineno=nextline+1 )
 	{
 		BackendDB *bd;
@@ -403,6 +403,9 @@ slapadd( int argc, char **argv )
 		entry_free( e );
 	}
 
+	if ( ldifrc < 0 )
+		rc = EXIT_FAILURE;
+
 	bvtext.bv_len = textlen;
 	bvtext.bv_val = textbuf;
 	bvtext.bv_val[0] = '\0';
diff --git a/servers/slapd/slapcommon.c b/servers/slapd/slapcommon.c
index 74b9e1b332..a5d4b4f5c9 100644
--- a/servers/slapd/slapcommon.c
+++ b/servers/slapd/slapcommon.c
@@ -233,6 +233,7 @@ slap_tool_init(
 	/* tools default to "none", so that at least LDAP_DEBUG_ANY 
 	 * messages show up; use -d 0 to reset */
 	slap_debug = LDAP_DEBUG_NONE;
+	ldif_debug = slap_debug;
 #endif
 	ldap_syslog = 0;
 
-- 
GitLab