diff --git a/libraries/libldap/controls.c b/libraries/libldap/controls.c
index c00836e35e600c3b439c122fa816bb16691e0e1f..e82a6c293fa84bbc7826a2a6f6f122fc6198cebf 100644
--- a/libraries/libldap/controls.c
+++ b/libraries/libldap/controls.c
@@ -140,3 +140,9 @@ LDAPControl *ldap_control_dup( LDAPControl *c )
 	new->ldctl_iscritical = c->ldctl_iscritical;
 	return new;
 }
+
+/* get the controls from the BerElement */
+int ldap_get_ber_controls( BerElement *be, LDAPControl ***cp)
+{
+	return LDAP_NOT_SUPPORTED;
+}
diff --git a/libraries/libldap/getentry.c b/libraries/libldap/getentry.c
index 069b2dcbe97f2df759e56623dc3ed5ebb36e806b..19636cefef19a6d7db9ce61d2d171d038b1aeed7 100644
--- a/libraries/libldap/getentry.c
+++ b/libraries/libldap/getentry.c
@@ -73,3 +73,46 @@ ldap_count_entries( LDAP *ld, LDAPMessage *chain )
 
 	return( i );
 }
+
+int
+ldap_get_entry_controls(
+	LDAP *ld,
+	LDAPMessage *entry, 
+	LDAPControl ***serverctrls)
+{
+	int rc;
+	BerElement be;
+
+	if ( ld == NULL || serverctrls == NULL ||
+		entry == NULL || entry->lm_msgtype == LDAP_RES_SEARCH_ENTRY )
+	{
+		return LDAP_PARAM_ERROR;
+	}
+
+	/* make a local copy of the BerElement */
+	SAFEMEMCPY(&be, entry->lm_ber, sizeof(be));
+
+	if ( ber_scanf( &be, "{xx" /*}*/ ) == LBER_ERROR ) {
+		rc = LDAP_DECODING_ERROR;
+		goto cleanup_and_return;
+	}
+
+	rc = ldap_get_ber_controls( &be, serverctrls );
+
+cleanup_and_return:
+	if( rc != LDAP_SUCCESS ) {
+		ld->ld_errno = rc;
+
+		if( ld->ld_matched != NULL )
+			free( ld->ld_matched );
+
+		ld->ld_matched = NULL;
+
+		if( ld->ld_error != NULL )
+			free( ld->ld_error );
+
+		ld->ld_error = NULL;
+	}
+
+	return rc;
+}
diff --git a/libraries/libldap/references.c b/libraries/libldap/references.c
index 3c317e1937ff649e01a3f10d5186bf0b40984856..a1e4731dc0cbf92bf3bf9307c38245a9f2006842 100644
--- a/libraries/libldap/references.c
+++ b/libraries/libldap/references.c
@@ -66,3 +66,72 @@ ldap_count_references( LDAP *ld, LDAPMessage *chain )
 
 	return( i );
 }
+
+int
+ldap_parse_reference( 
+	LDAP            *ld,    
+	LDAPMessage     *ref,
+	char            ***referralsp,
+	LDAPControl     ***serverctrls,
+	int             freeit)
+{
+	BerElement be;
+	char **refs = NULL;
+	int rc;
+
+	if( ld == NULL || ref == NULL ||
+		ref->lm_msgtype != LDAP_RES_SEARCH_REFERENCE )
+	{
+		return LDAP_PARAM_ERROR;
+	}
+
+	/* make a private copy of BerElement */
+	SAFEMEMCPY(&be, ref->lm_ber, sizeof(be));
+	
+	if ( ber_scanf( &be, "{v" /*}*/, &refs ) == LBER_ERROR ) {
+		rc = LDAP_DECODING_ERROR;
+		goto free_and_return;
+	}
+
+	if ( serverctrls == NULL ) {
+		rc = LDAP_SUCCESS;
+		goto free_and_return;
+	}
+
+	if ( ber_scanf( &be, /*{*/ "}" ) == LBER_ERROR ) {
+		rc = LDAP_DECODING_ERROR;
+		goto free_and_return;
+	}
+
+	rc = ldap_get_ber_controls( &be, serverctrls );
+
+free_and_return:
+
+	if( referralsp != NULL ) {
+		/* provide references regradless of return code */
+		*referralsp = refs;
+
+	} else {
+		ldap_value_free( refs );
+	}
+
+	if( freeit ) {
+		ldap_msgfree( ref );
+	}
+
+	if( rc != LDAP_SUCCESS ) {
+		ld->ld_errno = rc;
+
+		if( ld->ld_matched != NULL )
+			free( ld->ld_matched );
+
+		ld->ld_matched = NULL;
+
+		if( ld->ld_error != NULL )
+			free( ld->ld_error );
+
+		ld->ld_error = NULL;
+	}
+
+	return rc;
+}