diff --git a/include/lber.h b/include/lber.h
index f7386ce3f6c78c0f72af37dbff6363cbc3a0c7ad..9466a21bd9485c4e00d285680d9a7031f17f7b84 100644
--- a/include/lber.h
+++ b/include/lber.h
@@ -96,9 +96,12 @@ typedef int (*BERTranslateProc) LDAP_P((
 #define LBER_OPT_BER_DEBUG		0x02
 
 #define LBER_OPT_DEBUG_LEVEL	LBER_OPT_BER_DEBUG
+
 #define LBER_OPT_LOG_PRINT_FN	0x8001
+#define LBER_OPT_MEMORY_FN		0x8002
 
 typedef void (*BER_LOG_PRINT_FN) LDAP_P(( char *buf ));
+typedef void* (*BER_MEMORY_FN) LDAP_P(( void *p, size_t size ));
 
 /* LBER Sockbuf options */ 
 #define LBER_TO_FILE           0x01	/* to a file referenced by sb_fd   */
diff --git a/libraries/liblber/decode.c b/libraries/liblber/decode.c
index f41966297f3c7fc58db6525867115473fc63138b..67959921bf57d2fed90a70367638bdf904190680 100644
--- a/libraries/liblber/decode.c
+++ b/libraries/liblber/decode.c
@@ -750,6 +750,8 @@ ber_bvfree( struct berval *bv )
 {
 	assert(bv != NULL);			/* bv damn better point to something */
 
+	ber_int_options.lbo_valid = LBER_INITIALIZED;
+
 	if ( bv->bv_val != NULL )
 		LBER_FREE( bv->bv_val );
 	LBER_FREE( (char *) bv );
@@ -762,6 +764,8 @@ ber_bvecfree( struct berval **bv )
 
 	assert(bv != NULL);			/* bv damn better point to something */
 
+	ber_int_options.lbo_valid = LBER_INITIALIZED;
+
 	for ( i = 0; bv[i] != NULL; i++ )
 		ber_bvfree( bv[i] );
 	LBER_FREE( (char *) bv );
@@ -775,6 +779,8 @@ ber_bvdup(
 
 	assert( bv != NULL );
 
+	ber_int_options.lbo_valid = LBER_INITIALIZED;
+
 	if( bv == NULL ) {
 		return NULL;
 	}
diff --git a/libraries/liblber/io.c b/libraries/liblber/io.c
index d485a0b3fd23d9e9175e0834858139d9fa766725..b57714765f749fb327201c3326e4be3b3692ffb3 100644
--- a/libraries/liblber/io.c
+++ b/libraries/liblber/io.c
@@ -242,6 +242,8 @@ ber_alloc_t( int options )
 {
 	BerElement	*ber;
 
+    ber_int_options.lbo_valid = LBER_INITIALIZED;
+
 	ber = (BerElement *) LBER_CALLOC( 1, sizeof(BerElement) );
 
 	if ( ber == NULLBER )
@@ -293,6 +295,8 @@ ber_init_w_nullc( BerElement *ber, int options )
 {
 	assert( ber != NULL );
 
+    ber_int_options.lbo_valid = LBER_INITIALIZED;
+
 	(void) memset( (char *)ber, '\0', sizeof( BerElement ));
 	ber->ber_valid = LBER_VALID_BERELEMENT;
 	ber->ber_tag = LBER_DEFAULT;
@@ -313,6 +317,8 @@ ber_init( struct berval *bv )
 
 	assert( bv != NULL );
 
+    ber_int_options.lbo_valid = LBER_INITIALIZED;
+
 	if ( bv == NULL ) {
 		return NULL;
 	}
@@ -349,6 +355,8 @@ int ber_flatten(
  
 	assert( bvPtr != NULL );
 
+    ber_int_options.lbo_valid = LBER_INITIALIZED;
+
 	if(bvPtr == NULL) {
 		return( -1 );
 	}
diff --git a/libraries/liblber/lber-int.h b/libraries/liblber/lber-int.h
index 20e21da2b9ac8abbda2c5edab1fd5ce590689796..5bd643f04ff150233643b54f7fd4dde54e9c4ef5 100644
--- a/libraries/liblber/lber-int.h
+++ b/libraries/liblber/lber-int.h
@@ -23,6 +23,8 @@
 
 LDAP_BEGIN_DECL
 
+extern BER_MEMORY_FN	ber_int_realloc;
+
 struct lber_options {
 	short lbo_valid;
 #define LBER_UNINITIALIZED		0x0
@@ -190,12 +192,34 @@ ber_log_sos_dump LDAP_P((
 	int loglvl,
 	const Seqorset *sos ));
 
+
 /* memory.c */
 	/* simple macros to realloc for now */
-#define LBER_MALLOC(s)		(realloc(NULL,(s)))
-#define LBER_CALLOC(n,s)	(calloc((n),(s)))
-#define LBER_REALLOC(p,s)	(realloc((p),(s)))
-#define LBER_FREE(p)		(realloc((p),(size_t)0))
+#define LBER_MALLOC(s)	\
+	(ber_int_realloc \
+		? (*ber_int_realloc)(NULL,(s)) \
+		: realloc(NULL,(s)))
+
+#define LBER_CALLOC(n,s) \
+	(ber_int_realloc \
+		? ber_int_calloc((n),(s)) \
+		: calloc((n),(s)))
+
+#define LBER_REALLOC(p,s) \
+	(ber_int_realloc \
+		? (*ber_int_realloc)((p),(s)) \
+		: realloc((p),(s)))
+
+#define LBER_FREE(p) \
+	(ber_int_realloc \
+		? (*ber_int_realloc)((p),(size_t)0) \
+		: realloc((p),(size_t)0))
+
+LDAP_F( void * )
+ber_int_calloc LDAP_P((
+	size_t n,
+	size_t size ));
+
 
 /* sockbuf.c */
 
diff --git a/libraries/liblber/memory.c b/libraries/liblber/memory.c
index 39e19c5c111f37a0be81e52bcd7f69613fbbbfb1..ee5f4e8edea2fb967d8a312d92b7f18d254c0817 100644
--- a/libraries/liblber/memory.c
+++ b/libraries/liblber/memory.c
@@ -11,24 +11,42 @@
 void
 ber_memfree( void *p )
 {
+    ber_int_options.lbo_valid = LBER_INITIALIZED;
 	LBER_FREE( p );
 }
 
 void *
 ber_memalloc( size_t s )
 {
+    ber_int_options.lbo_valid = LBER_INITIALIZED;
 	return LBER_MALLOC( s );
 }
 
 void *
 ber_memcalloc( size_t n, size_t s )
 {
+    ber_int_options.lbo_valid = LBER_INITIALIZED;
 	return LBER_CALLOC( n, s );
 }
 
 void *
 ber_memrealloc( void* p, size_t s )
 {
+    ber_int_options.lbo_valid = LBER_INITIALIZED;
 	return LBER_REALLOC( p, s );
 }
 
+BER_MEMORY_FN ber_int_realloc = NULL;
+
+void *
+ber_int_calloc( size_t n, size_t s )
+{
+    ber_int_options.lbo_valid = LBER_INITIALIZED;
+
+	{
+		size_t size = n * s;
+		void *p = (*ber_int_realloc)( NULL, size );
+		return p ?  memset( p, 0, size ) : p;
+	}
+}
+
diff --git a/libraries/liblber/options.c b/libraries/liblber/options.c
index 0da332e8e74b012966e4eaa3fe55344b4cf19996..eafc812edaed505579964857d52188dcc8b727c4 100644
--- a/libraries/liblber/options.c
+++ b/libraries/liblber/options.c
@@ -20,6 +20,8 @@ ber_get_option(
 	BerElement *ber;
 	Sockbuf *sb;
 
+	ber_int_options.lbo_valid = LBER_INITIALIZED;
+
 	if(outvalue == NULL) {
 		/* no place to get to */
 		return LBER_OPT_ERROR;
@@ -65,6 +67,17 @@ ber_set_option(
 	BerElement *ber;
 	Sockbuf *sb;
 
+	if( (ber_int_options.lbo_valid == LBER_UNINITIALIZED)
+		&& ( option == LBER_OPT_MEMORY_FN )
+		&& ( invalue != NULL ))
+	{
+		ber_int_realloc = (BER_MEMORY_FN) invalue;
+		ber_int_options.lbo_valid = LBER_INITIALIZED;
+		return LBER_OPT_SUCCESS;
+	}
+
+	ber_int_options.lbo_valid = LBER_INITIALIZED;
+
 	if(invalue == NULL) {
 		/* no place to set from */
 		return LBER_OPT_ERROR;
diff --git a/libraries/liblber/sockbuf.c b/libraries/liblber/sockbuf.c
index 41a1754a6b959cf2a9f4c68999ae95b8f5aae34c..19b92bf47f12d5b1599b877b7266ffea497dafcb 100644
--- a/libraries/liblber/sockbuf.c
+++ b/libraries/liblber/sockbuf.c
@@ -330,7 +330,11 @@ sockbuf_copy_out( Sockbuf *sb, char **buf, long len )
 
 Sockbuf *ber_sockbuf_alloc( void )
 {
-	Sockbuf *sb = LBER_CALLOC(1, sizeof(Sockbuf));
+	Sockbuf *sb;
+
+	ber_int_options.lbo_valid = LBER_INITIALIZED;
+
+	sb = LBER_CALLOC(1, sizeof(Sockbuf));
 
 	if( sb == NULL ) return NULL;
 
@@ -694,6 +698,8 @@ int ber_pvt_sb_init( Sockbuf *sb )
 {
 	assert( sb != NULL);
 
+	ber_int_options.lbo_valid = LBER_INITIALIZED;
+
    sb->sb_valid=LBER_VALID_SOCKBUF;
    sb->sb_options = 0;
    sb->sb_debug = 0;