diff --git a/Make-common b/Make-common
index 405842cc4fa9a0aedce8443db9ed3654cbabafbb..5867e372625bc41de289ac647f2de0a7e4a207e1 100644
--- a/Make-common
+++ b/Make-common
@@ -197,6 +197,10 @@ LDAP_DEBUG=-DLDAP_DEBUG
 # uncomment this line to enable support for LDAP referrals in libldap
 LDAP_REFERRALS=-DLDAP_REFERRALS
 
+# uncomment this line to enable support for CRYPT passwords in LDBM
+# requires UNIX crypt(3)
+LDAP_CRYPT=-DLDAP_CRYPT
+
 # uncomment this line to use soundex for approximate matches in slapd.
 # the default is to use the metaphone algorithm.
 #PHONETIC=-DSOUNDEX
diff --git a/build/Make-append b/build/Make-append
index 67a2f29bb05ed286bbce22a89c0354552081bf69..32c3d1cc9cc3b05f0f6574c83257dea1f0625d8f 100644
--- a/build/Make-append
+++ b/build/Make-append
@@ -21,7 +21,7 @@
 # DEFS are included in CFLAGS
 DEFS	= $(PLATFORMCFLAGS) $(LDAP_DEBUG) $(KERBEROS) $(AFSKERBEROS) \
 		$(UOFM) $(UOFA) $(NO_USERINTERFACE) $(CLDAP) $(NO_CACHE) \
-		$(LDAP_REFERRALS) $(LDAP_DNS) $(STR_TRANSLATION) \
+		$(LDAP_REFERRALS) $(LDAP_CRYPT) $(LDAP_DNS) $(STR_TRANSLATION) \
 		$(LIBLDAP_CHARSETS) $(LIBLDAP_DEF_CHARSET) \
 		$(SLAPD_BACKENDS) $(LDBMBACKEND) $(LDBMINCLUDE) $(PHONETIC)
 
diff --git a/build/platforms/freebsd-gcc/Make-platform b/build/platforms/freebsd-gcc/Make-platform
index 895b32f2af7e0fbaab628022a6f008b596a33141..9ddba04dc701458fd1c7f88b7352cd8358a81339 100644
--- a/build/platforms/freebsd-gcc/Make-platform
+++ b/build/platforms/freebsd-gcc/Make-platform
@@ -14,3 +14,6 @@
 CC	= gcc
 
 PLATFORMCFLAGS=	-Dfreebsd
+
+# uncomment this line if using for LDAP_CRYPT
+PLATFORMLIBS=	-lcrypt
diff --git a/servers/slapd/back-ldbm/bind.c b/servers/slapd/back-ldbm/bind.c
index 88fd4030c41df52a20815451fdc6491f4f431449..a4cbcd397fc2d33c44fb155705ed8badd7ee3d15 100644
--- a/servers/slapd/back-ldbm/bind.c
+++ b/servers/slapd/back-ldbm/bind.c
@@ -10,6 +10,15 @@
 #include "krb.h"
 #endif
 
+#ifdef LDAP_CRYPT
+/* change for crypted passwords -- lukeh */
+#ifdef __NeXT__
+extern char *crypt (char *key, char *salt);
+#else
+#include <unistd.h>
+#endif
+#endif /* LDAP_CRYPT */
+
 extern Entry		*dn2entry();
 extern Attribute	*attr_find();
 
@@ -17,6 +26,40 @@ extern Attribute	*attr_find();
 extern int	krbv4_ldap_auth();
 #endif
 
+#ifdef LDAP_CRYPT
+pthread_mutex_t crypt_mutex;
+
+static int
+crypted_value_find(
+	struct berval       **vals,
+	struct berval       *v,
+	int                 syntax,
+	int                 normalize,
+	struct berval		*cred
+)
+{
+	int     i;
+	for ( i = 0; vals[i] != NULL; i++ ) {
+		if ( syntax != SYNTAX_BIN && 
+			strncasecmp( "{CRYPT}", vals[i]->bv_val, (sizeof("{CRYPT}") - 1 ) ) == 0 ) {
+				char *userpassword = vals[i]->bv_val + sizeof("{CRYPT}") - 1;
+				pthread_mutex_lock( &crypt_mutex );
+				if ( ( !strcmp( userpassword, crypt( cred->bv_val, userpassword ) ) != 0 ) ) {
+					pthread_mutex_unlock( &crypt_mutex );
+					return ( 0 );
+				}
+				pthread_mutex_unlock( &crypt_mutex );
+		} else {
+                if ( value_cmp( vals[i], v, syntax, normalize ) == 0 ) {
+                        return( 0 );
+                }
+        }
+	}
+
+	return( 1 );
+}
+#endif /* LDAP_CRYPT */
+
 int
 ldbm_back_bind(
     Backend		*be,
@@ -81,13 +124,18 @@ ldbm_back_bind(
 			return( 1 );
 		}
 
-		if ( value_find( a->a_vals, cred, a->a_syntax, 0 ) != 0 ) {
+#ifdef LDAP_CRYPT
+		if ( crypted_value_find( a->a_vals, cred, a->a_syntax, 0, cred ) != 0 )
+#else
+		if ( value_find( a->a_vals, cred, a->a_syntax, 0 ) != 0 )
+#endif
+{
 			if ( be_isroot_pw( be, dn, cred ) ) {
 				/* front end will send result */
 				return( 0 );
 			}
 			send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
-			    NULL, NULL );
+				NULL, NULL );
 			cache_return_entry( &li->li_cache, e );
 			return( 1 );
 		}
diff --git a/servers/slapd/back-ldbm/init.c b/servers/slapd/back-ldbm/init.c
index b9c5c2f3fa1feac501b93271679a854ce25819ec..de8c59a236fc5530465860d9377ffa3ca85783a2 100644
--- a/servers/slapd/back-ldbm/init.c
+++ b/servers/slapd/back-ldbm/init.c
@@ -15,6 +15,10 @@ ldbm_back_init(
 	char		*argv[ 4 ];
 	int		i;
 
+#ifdef LDAP_CRYPT
+	extern pthread_mutex_t crypt_mutex;
+#endif /* LDAP_CRYPT */
+
 	/* allocate backend-specific stuff */
 	li = (struct ldbminfo *) ch_calloc( 1, sizeof(struct ldbminfo) );
 
@@ -59,6 +63,9 @@ ldbm_back_init(
 	pthread_mutex_init( &li->li_cache.c_mutex, pthread_mutexattr_default );
 	pthread_mutex_init( &li->li_nextid_mutex, pthread_mutexattr_default );
 	pthread_mutex_init( &li->li_dbcache_mutex, pthread_mutexattr_default );
+#ifdef LDAP_CRYPT
+	pthread_mutex_init( &crypt_mutex, pthread_mutexattr_default );
+#endif /* LDAP_CRYPT */
 	pthread_cond_init( &li->li_dbcache_cv, pthread_condattr_default );
 	for ( i = 0; i < MAXDBCACHE; i++ ) {
 		pthread_mutex_init( &li->li_dbcache[i].dbc_mutex,