diff --git a/CHANGES b/CHANGES
index 5aa73d1e322fa6338e4b7ea7f18efc1aef17b39f..a28a9f64cdd747aabf6e67861d338daec0999cb7 100644
--- a/CHANGES
+++ b/CHANGES
@@ -12,6 +12,7 @@ OpenLDAP 2.4.13 Engineering
 	Fixed slapd-bdb/hdb invalid db crash (ITS#5698)
 	Added slapd-bdb/hdb dbpagesize keyword
 	Added slapd-bdb/hdb checksum keyword
+	Fixed slapd-ldap snprintf buffer overflow test (ITS#4467)
 	Fixed slapo-chain/translucent back-config support (ITS#5736)
 	Fixed slapo-chain segv with search references (ITS#5742)
 	Fixed slapo-collect compile with C89 (ITS#5747)
diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c
index d95f6815b9e3564744bf21bc5e42c82709dbc803..8800821ddd311990484f7ccff5ec918f4af0998b 100644
--- a/servers/slapd/back-ldap/config.c
+++ b/servers/slapd/back-ldap/config.c
@@ -510,53 +510,51 @@ slap_retry_info_unparse(
 	slap_retry_info_t	*ri,
 	struct berval		*bvout )
 {
-	int		i;
 	char		buf[ BUFSIZ * 2 ],
 			*ptr = buf;
-	struct berval	bv = BER_BVNULL;
+	int		i, len, restlen = (int) sizeof( buf );
+	struct berval	bv;
 
 	assert( ri != NULL );
 	assert( bvout != NULL );
 
 	BER_BVZERO( bvout );
 
-#define WHATSLEFT	( &buf[ sizeof( buf ) ] - ptr )
-
 	for ( i = 0; ri->ri_num[ i ] != SLAP_RETRYNUM_TAIL; i++ ) {
 		if ( i > 0 ) {
-			if ( WHATSLEFT <= 1 ) {
+			if ( --restlen <= 0 ) {
 				return 1;
 			}
 			*ptr++ = ';';
 		}
 
-		if ( lutil_unparse_time( ptr, WHATSLEFT, (long)ri->ri_interval[i] ) ) {
+		if ( lutil_unparse_time( ptr, restlen, ri->ri_interval[i] ) < 0 ) {
 			return 1;
 		}
-		ptr += strlen( ptr );
-
-		if ( WHATSLEFT <= 1 ) {
+		len = (int) strlen( ptr );
+		if ( (restlen -= len + 1) <= 0 ) {
 			return 1;
 		}
+		ptr += len;
 		*ptr++ = ',';
 
 		if ( ri->ri_num[i] == SLAP_RETRYNUM_FOREVER ) {
-			if ( WHATSLEFT <= 1 ) {
+			if ( --restlen <= 0 ) {
 				return 1;
 			}
 			*ptr++ = '+';
 
 		} else {
-			ptr += snprintf( ptr, WHATSLEFT, "%d", ri->ri_num[i] );
-			if ( WHATSLEFT <= 0 ) {
+			len = snprintf( ptr, restlen, "%d", ri->ri_num[i] );
+			if ( (restlen -= len) <= 0 || len < 0 ) {
 				return 1;
 			}
+			ptr += len;
 		}
 	}
 
 	bv.bv_val = buf;
 	bv.bv_len = ptr - buf;
-
 	ber_dupbv( bvout, &bv );
 
 	return 0;