diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c
index 9fb538bcbe354441aae59aa004045241b4e30928..506757c46b6d73370dcec5680f7aa4d8ab315964 100644
--- a/clients/tools/ldapsearch.c
+++ b/clients/tools/ldapsearch.c
@@ -428,7 +428,7 @@ void print_entry(
 {
     char		*a, *dn, *ufn, tmpfname[ 64 ];
     int			i, j, notascii;
-    BerElement		*ber;
+    BerElement		*ber = NULL;
     struct berval	**bvals;
     FILE		*tmpfp;
 
@@ -505,6 +505,10 @@ void print_entry(
 	    ber_bvecfree( bvals );
 	}
     }
+
+	if( ber != NULL ) {
+		ber_free( ber, 0 );
+	}
 }
 
 
diff --git a/clients/ud/print.c b/clients/ud/print.c
index ad62c50a4cf2096fbdce2bd9cd96391d9da94413..aca1c30f37cfb6a2cd301b000863f60cd6f76d52 100644
--- a/clients/ud/print.c
+++ b/clients/ud/print.c
@@ -82,7 +82,6 @@ parse_answer( LDAPMessage *s )
 {
 	int idx;
 	char **rdns;
-	BerElement *cookie;
 	register LDAPMessage *ep;
 	register char *ap;
 
@@ -98,6 +97,7 @@ parse_answer( LDAPMessage *s )
 		printf(" Done clearing entry\n");
 #endif
 	for (ep = ldap_first_entry(ld, s); ep != NULL; ep = ldap_next_entry(ld, ep)) {
+		BerElement *cookie = NULL;
 #ifdef DEBUG
 		if (debug & D_PARSE)
 			printf(" Determining DN and name\n");
@@ -126,6 +126,10 @@ parse_answer( LDAPMessage *s )
 			}
 			add_value(&(Entry.attrs[idx]), ep, ap);
 		}
+
+		if( cookie != NULL ) {
+			ber_free( cookie, 0 );
+		}
 	}
 #ifdef DEBUG
 	if (debug & D_PARSE)
diff --git a/doc/man/man3/ldap_first_attribute.3 b/doc/man/man3/ldap_first_attribute.3
index 376c3f8fbef661b8ac9c526c61a274fc28aeb6b1..1fa6ff4d9280121e7e2d43221dba8d635de00da2 100644
--- a/doc/man/man3/ldap_first_attribute.3
+++ b/doc/man/man3/ldap_first_attribute.3
@@ -43,15 +43,9 @@ allocated to keep track of its current position.  This pointer should
 be passed to subsequent calls to
 .B ldap_next_attribute()
 and is used used
-to effectively step through the entry's attributes.  This pointer
-is freed by
-.B ldap_next_attribute()
-when there are no more attributes (that
-is, when
-.B ldap_next_attribute()
-returns NULL).  Otherwise, the caller is
-responsible for freeing the BerElement pointed to by \fIberptr\fP when
-it is no longer needed by calling
+to effectively step through the entry's attributes.  The caller is
+solely responsible for freeing the BerElement pointed to by \fIberptr\fP
+when it is no longer needed by calling
 .BR ber_free (3).
 When calling
 .BR ber_free (3)
@@ -69,9 +63,8 @@ for a description of possible error codes.
 .SH NOTES
 The
 .B ldap_first_attribute()
-routine dyanamically allocated memory that may need to
-be freed by the caller via
-.BR ber_free (3).
+routine dyanamically allocated memory that must be freed by the caller via
+.BR ber_free (3).   
 .SH SEE ALSO
 .BR ldap(3),
 .BR ldap_first_entry(3),
diff --git a/libraries/libldap/getattr.c b/libraries/libldap/getattr.c
index f7ceb367c0764b0480a4f656763bef52cb13b8aa..8e655da12efea0cb1aeb4a518ccc0f9f5b7780c2 100644
--- a/libraries/libldap/getattr.c
+++ b/libraries/libldap/getattr.c
@@ -29,6 +29,7 @@ ldap_first_attribute( LDAP *ld, LDAPMessage *entry, BerElement **ber )
 	Debug( LDAP_DEBUG_TRACE, "ldap_first_attribute\n", 0, 0, 0 );
 
 	if ( (*ber = ldap_alloc_ber_with_options( ld )) == NULLBER ) {
+		*ber = NULL;
 		return( NULL );
 	}
 
@@ -45,6 +46,7 @@ ldap_first_attribute( LDAP *ld, LDAPMessage *entry, BerElement **ber )
 	    == LBER_ERROR ) {
 		ld->ld_errno = LDAP_DECODING_ERROR;
 		ber_free( *ber, 0 );
+		*ber = NULL;
 		return( NULL );
 	}
 
@@ -64,7 +66,7 @@ ldap_next_attribute( LDAP *ld, LDAPMessage *entry, BerElement *ber )
 	if ( ber_scanf( ber, "{sx}", ld->ld_attrbuffer, &len ) 
 	    == LBER_ERROR ) {
 		ld->ld_errno = LDAP_DECODING_ERROR;
-		ber_free( ber, 0 );
+		/* ber_free( ber, 0 ); *//* don't free the BerElement */
 		return( NULL );
 	}
 
diff --git a/libraries/libldap/test.c b/libraries/libldap/test.c
index cbcf189e4419c86fae156891ff9ff45c301b8bca..23088a116620cb41626733ebcf55085a7bc48a1b 100644
--- a/libraries/libldap/test.c
+++ b/libraries/libldap/test.c
@@ -914,14 +914,14 @@ print_ldap_result( LDAP *ld, LDAPMessage *lm, char *s )
 static void
 print_search_entry( LDAP *ld, LDAPMessage *res )
 {
-	BerElement	*ber;
-	char		*a, *dn, *ufn;
-	struct berval	**vals;
-	int		i;
 	LDAPMessage	*e;
 
 	for ( e = ldap_first_entry( ld, res ); e != NULLMSG;
-	    e = ldap_next_entry( ld, e ) ) {
+	    e = ldap_next_entry( ld, e ) )
+	{
+		BerElement	*ber = NULL;
+		char *a, *dn, *ufn;
+
 		if ( e->lm_msgtype == LDAP_RES_SEARCH_RESULT )
 			break;
 
@@ -935,12 +935,16 @@ print_search_entry( LDAP *ld, LDAPMessage *res )
 		free( ufn );
 
 		for ( a = ldap_first_attribute( ld, e, &ber ); a != NULL;
-		    a = ldap_next_attribute( ld, e, ber ) ) {
+		    a = ldap_next_attribute( ld, e, ber ) )
+		{
+			struct berval	**vals;
+
 			printf( "\t\tATTR: %s\n", a );
 			if ( (vals = ldap_get_values_len( ld, e, a ))
 			    == NULL ) {
 				printf( "\t\t\t(no values)\n" );
 			} else {
+				int i;
 				for ( i = 0; vals[i] != NULL; i++ ) {
 					int	j, nonascii;
 
@@ -965,6 +969,10 @@ print_search_entry( LDAP *ld, LDAPMessage *res )
 				ber_bvecfree( vals );
 			}
 		}
+
+		if(ber != NULL) {
+			ber_free( ber, 0 );
+		}
 	}
 
 	if ( res->lm_msgtype == LDAP_RES_SEARCH_RESULT
diff --git a/libraries/libldap/tmplout.c b/libraries/libldap/tmplout.c
index 291ec3a785d5e83bec01c8b150d0d824c0fc4d76..9e5f9af0fb10d6385fa681f4bb866fc7ae1dcfc0 100644
--- a/libraries/libldap/tmplout.c
+++ b/libraries/libldap/tmplout.c
@@ -265,6 +265,10 @@ do_entry2text(
 		ldap_value_free( vals );
 	    }
 	}
+
+	if( ber != NULL) {
+		ber_free( ber, 0 );
+	}
     } else {
 	for ( rowp = ldap_first_tmplrow( tmpl );
 		NONFATAL_LDAP_ERR( err ) && rowp != NULLTMPLITEM;