diff -ru dovecot-0.99.10.6/src/auth/passdb-ldap.c dovecot-0.99.10.6.md5-quirk/src/auth/passdb-ldap.c
--- dovecot-0.99.10.6/src/auth/passdb-ldap.c	Fri Mar 21 02:55:57 2003
+++ dovecot-0.99.10.6.md5-quirk/src/auth/passdb-ldap.c	Wed Jun 30 13:43:35 2004
@@ -11,6 +11,9 @@
 #include "password-scheme.h"
 #include "db-ldap.h"
 #include "passdb.h"
+#include "base64.h"
+#include "buffer.h"
+#include "hex-binary.h"
 
 #include <ldap.h>
 #include <stdlib.h>
@@ -54,6 +57,7 @@
         struct auth_request *auth_request = request->context;
 	LDAPMessage *entry;
 	BerElement *ber;
+	buffer_t *buf;
 	char *attr, **vals;
 	const char *user, *password, *scheme;
 	int ret;
@@ -102,6 +106,16 @@
 	if (scheme == NULL) {
 		scheme = conn->set.default_pass_scheme;
 		i_assert(scheme != NULL);
+	}
+
+	/* Special case for OpenLDAP's MD5 type */
+	if (strcasecmp(scheme, "MD5") == 0) {
+		buf = buffer_create_static(data_stack_pool, 16);
+		if (base64_decode(password, strlen(password), NULL, buf) == 1
+				&& buffer_get_used_size(buf) == 16) {
+			password = binary_to_hex(buffer_get_data(buf, NULL), 16);
+			scheme = "PLAIN-MD5";
+		}
 	}
 
 	if (ldap_request->credentials != -1) {
diff -ru dovecot-0.99.10.6/src/auth/password-scheme.c dovecot-0.99.10.6.md5-quirk/src/auth/password-scheme.c
--- dovecot-0.99.10.6/src/auth/password-scheme.c	Sat Jun 19 05:17:11 2004
+++ dovecot-0.99.10.6.md5-quirk/src/auth/password-scheme.c	Wed Jun 30 15:26:09 2004
@@ -3,6 +3,8 @@
 #include "lib.h"
 #include "base64.h"
 #include "hex-binary.h"
+#include "base64.h"
+#include "buffer.h"
 #include "md5.h"
 #include "md5crypt.h"
 #include "mycrypt.h"
@@ -22,6 +24,10 @@
 {
 	unsigned char md5_digest[16];
 	const char *realm, *str;
+	buffer_t *buf;
+	size_t size;
+	const char *data;
+	struct md5_context ctx;
 
 	if (password == NULL)
 		return 0;
@@ -66,6 +72,29 @@
 		return strcasecmp(str, password) == 0;
 	}
 
+	/* format: base64-encoded MD5 hash and salt */
+	if (strcasecmp(scheme, "SMD5") == 0) {
+		buf = buffer_create_static(data_stack_pool,
+				MAX_BASE64_DECODED_SIZE(strlen(password)+1));
+
+		if (base64_decode(password, strlen(password), NULL, buf) == 1) {
+			data = buffer_get_data(buf, &size);
+			if (size <= 16) {
+				i_error("password-verify(%s): invalid SMD5", user);
+				return -1;
+			}
+
+			md5_init(&ctx);
+			md5_update(&ctx, plaintext, strlen(plaintext));
+			md5_update(&ctx, &data[16], size-16);
+			md5_final(&ctx, md5_digest);
+			return memcmp(md5_digest, data, 16) == 0;
+                } else {
+			i_error("password-verify(%s): couldn't decode SMD5", user);
+			return -1;
+		}
+	}
+
 	return -1;
 }
 
@@ -97,6 +126,14 @@
 
 	scheme = t_strdup_until(*password + 1, p);
 	*password = p + 1;
+
+	/* LDAP's RFC2307 specifies the MD5 scheme for what we call PLAIN-MD5.
+	 * Implementations use base64 encoding for the hash, so we can
+	 * detect the genuine {MD5}'s MCF format - base64 doesn't use '$'. */
+	if (strncasecmp(scheme, "MD5", 3) == 0 &&
+		strncmp(*password, "$1$", 3) != 0) {
+		scheme = "PLAIN-MD5";
+	}
 	return scheme;
 }
 
