diff -ru dovecot-0.99.7/src/auth/auth-digest-md5.c dovecot-0.99.7p1/src/auth/auth-digest-md5.c
--- dovecot-0.99.7/src/auth/auth-digest-md5.c	2003-01-11 21:55:56.000000000 +0200
+++ dovecot-0.99.7p1/src/auth/auth-digest-md5.c	2003-01-21 09:39:28.000000000 +0200
@@ -195,8 +195,14 @@
 
 		if (i == 0) {
 			/* verify response */
-			if (memcmp(response_hex, auth->response, 32) != 0)
+			if (memcmp(response_hex, auth->response, 32) != 0) {
+				if (verbose) {
+					i_info("digest-md5(%s): "
+					       "password mismatch",
+					       auth->username);
+				}
 				return FALSE;
+			}
 		} else {
 			auth->rspauth = p_strconcat(auth->pool, "rspauth=",
 						    response_hex, NULL);
@@ -506,7 +512,7 @@
 		auth->qop_value = p_strdup(auth->pool, "auth");
 
 	if (!failed && !verify_auth(auth)) {
-		*error = "Authentication failed";
+		*error = NULL;
 		failed = TRUE;
 	}
 
@@ -557,6 +563,11 @@
 		return;
 	}
 
+	if (error == NULL)
+                error = "Authentication failed";
+	else if (verbose)
+		i_info("digest-md5: %s", error);
+
 	/* failed */
 	reply.result = AUTH_RESULT_FAILURE;
 	callback(&reply, error, context);
diff -ru dovecot-0.99.7/src/auth/common.h dovecot-0.99.7p1/src/auth/common.h
--- dovecot-0.99.7/src/auth/common.h	2003-01-05 15:09:51.000000000 +0200
+++ dovecot-0.99.7p1/src/auth/common.h	2003-01-21 09:39:28.000000000 +0200
@@ -8,5 +8,6 @@
 #define LOGIN_LISTEN_FD 3
 
 extern struct ioloop *ioloop;
+extern int verbose;
 
 #endif
diff -ru dovecot-0.99.7/src/auth/login-connection.c dovecot-0.99.7p1/src/auth/login-connection.c
--- dovecot-0.99.7/src/auth/login-connection.c	2003-01-05 17:19:50.000000000 +0200
+++ dovecot-0.99.7p1/src/auth/login-connection.c	2003-01-21 09:39:28.000000000 +0200
@@ -84,6 +84,10 @@
 		login_connection_destroy(conn);
 	} else {
 		conn->pid = rec.pid;
+		if (verbose) {
+			i_info("Login process %d sent handshake: PID %s",
+			       conn->fd, dec2str(conn->pid));
+		}
 	}
 }
 
@@ -173,6 +177,9 @@
 {
 	struct login_connection *conn;
 
+	if (verbose)
+		i_info("Login process %d connected", fd);
+
 	conn = i_new(struct login_connection, 1);
 
 	conn->fd = fd;
@@ -199,6 +206,9 @@
 {
 	struct login_connection **pos;
 
+	if (verbose)
+		i_info("Login process %d disconnected", conn->fd);
+
 	for (pos = &connections; *pos != NULL; pos = &(*pos)->next) {
 		if (*pos == conn) {
 			*pos = conn->next;
diff -ru dovecot-0.99.7/src/auth/main.c dovecot-0.99.7p1/src/auth/main.c
--- dovecot-0.99.7/src/auth/main.c	2003-01-08 23:13:05.000000000 +0200
+++ dovecot-0.99.7p1/src/auth/main.c	2003-01-21 09:39:28.000000000 +0200
@@ -17,6 +17,8 @@
 #include <syslog.h>
 
 struct ioloop *ioloop;
+int verbose = FALSE;
+
 static struct io *io_listen;
 
 static void sig_quit(int signo __attr_unused__)
@@ -69,6 +71,8 @@
 {
 	lib_init_signals(sig_quit);
 
+	verbose = getenv("VERBOSE") != NULL;
+
 	auth_init();
 	cookies_init();
 	login_connections_init();
diff -ru dovecot-0.99.7/src/auth/userinfo-pam.c dovecot-0.99.7p1/src/auth/userinfo-pam.c
--- dovecot-0.99.7/src/auth/userinfo-pam.c	2003-01-05 15:09:51.000000000 +0200
+++ dovecot-0.99.7p1/src/auth/userinfo-pam.c	2003-01-21 09:39:28.000000000 +0200
@@ -148,25 +148,45 @@
 	return PAM_SUCCESS;
 }
 
-static int pam_auth(pam_handle_t *pamh)
+static int pam_auth(pam_handle_t *pamh, const char *user)
 {
 	char *item;
 	int status;
 
-	if ((status = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
+	if ((status = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
+		if (verbose) {
+			i_info("PAM: pam_authenticate(%s) failed: %s",
+			       user, pam_strerror(pamh, status));
+		}
 		return status;
+	}
 
 #ifdef HAVE_PAM_SETCRED
-	if ((status = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS)
+	if ((status = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS) {
+		if (verbose) {
+			i_info("PAM: pam_setcred(%s) failed: %s",
+			       user, pam_strerror(pamh, status));
+		}
 		return status;
+	}
 #endif
 
-	if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
+	if ((status = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS) {
+		if (verbose) {
+			i_info("PAM: pam_acct_mgmt(%s) failed: %s",
+			       user, pam_strerror(pamh, status));
+		}
 		return status;
+	}
 
 	status = pam_get_item(pamh, PAM_USER, (linux_const void **)&item);
-	if (status != PAM_SUCCESS)
+	if (status != PAM_SUCCESS) {
+		if (verbose) {
+			i_info("PAM: pam_get_item(%s) failed: %s",
+			       user, pam_strerror(pamh, status));
+		}
 		return status;
+	}
 
 	return PAM_SUCCESS;
 }
@@ -187,12 +207,18 @@
 	userpass.pass = password;
 
 	status = pam_start(service_name, user, &conv, &pamh);
-	if (status != PAM_SUCCESS)
+	if (status != PAM_SUCCESS) {
+		if (verbose) {
+			i_info("PAM: pam_start(%s) failed: %s",
+			       user, pam_strerror(pamh, status));
+		}
 		return FALSE;
+	}
 
-	status = pam_auth(pamh);
+	status = pam_auth(pamh, user);
 	if ((status2 = pam_end(pamh, status)) != PAM_SUCCESS) {
-		i_error("pam_end() failed: %s", pam_strerror(pamh, status2));
+		i_error("pam_end(%s) failed: %s",
+			user, pam_strerror(pamh, status2));
 		return FALSE;
 	}
 
@@ -201,8 +227,10 @@
 
 	/* password ok, save the user info */
 	pw = getpwnam(user);
-	if (pw == NULL)
+	if (pw == NULL) {
+		i_error("PAM: getpwnam(%s) failed: %m", user);
 		return FALSE;
+	}
 
 	safe_memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
 	passwd_fill_cookie_reply(pw, reply);
diff -ru dovecot-0.99.7/src/auth/userinfo-passwd-file.c dovecot-0.99.7p1/src/auth/userinfo-passwd-file.c
--- dovecot-0.99.7/src/auth/userinfo-passwd-file.c	2003-01-11 21:55:56.000000000 +0200
+++ dovecot-0.99.7p1/src/auth/userinfo-passwd-file.c	2003-01-21 09:39:28.000000000 +0200
@@ -67,8 +67,11 @@
 				  strlen(pu->realm) - 1);
 
 		pw = getpwnam(user);
-		if (pw == NULL)
+		if (pw == NULL) {
+			i_error("passwd-file(%s): missing info and "
+				"not found with getpwnam()", user);
 			return FALSE;
+		}
 
 		passwd_fill_cookie_reply(pw, reply);
 	}
@@ -115,21 +118,35 @@
 
 	/* find it from all realms */
 	pu = hash_lookup(passwd_file->users, user);
-	if (pu == NULL)
+	if (pu == NULL) {
+		if (verbose)
+			i_info("passwd-file(%s): unknown user", user);
 		return FALSE;
+	}
 
 	/* verify that password matches */
 	switch (pu->password_type) {
 	case PASSWORD_DES:
-		if (strcmp(mycrypt(password, pu->password), pu->password) != 0)
+		if (strcmp(mycrypt(password, pu->password),
+			   pu->password) != 0) {
+			if (verbose) {
+				i_info("passwd-file(%s): DES password mismatch",
+				       user);
+			}
 			return FALSE;
+		}
 		break;
 	case PASSWORD_MD5:
 		md5_get_digest(password, strlen(password), digest);
 		str = binary_to_hex(digest, sizeof(digest));
 
-		if (strcmp(str, pu->password) != 0)
+		if (strcmp(str, pu->password) != 0) {
+			if (verbose) {
+				i_info("passwd-file(%s): MD5 password mismatch",
+				       user);
+			}
 			return FALSE;
+		}
 		break;
 	case PASSWORD_DIGEST_MD5:
 		/* user:realm:passwd */
@@ -140,8 +157,13 @@
 		md5_get_digest(str, strlen(str), digest);
 		str = binary_to_hex(digest, sizeof(digest));
 
-		if (strcmp(str, pu->password) != 0)
+		if (strcmp(str, pu->password) != 0) {
+			if (verbose) {
+				i_info("passwd-file(%s): "
+				       "DIGEST-MD5 password mismatch", user);
+			}
 			return FALSE;
+		}
 		break;
 	default:
                 i_unreached();
@@ -167,16 +189,22 @@
 		t_strconcat(user, ":", realm, NULL);
 
 	pu = hash_lookup(passwd_file->users, id);
-	if (pu == NULL)
+	if (pu == NULL) {
+		if (verbose)
+			i_info("passwd-file(%s): unknown user", user);
 		return FALSE;
+	}
 
 	/* found */
 	i_assert(strlen(pu->password) == 32);
 
 	buf = buffer_create_data(data_stack_pool, digest, 16);
-	if (!hex_to_binary(pu->password, buf))
+	if (!hex_to_binary(pu->password, buf)) {
+		if (verbose)
+			i_info("passwd-file(%s): invalid password field", user);
 		return FALSE;
-	
+	}
+
 	return get_reply_data(pu, reply);
 }
 
diff -ru dovecot-0.99.7/src/auth/userinfo-passwd.c dovecot-0.99.7p1/src/auth/userinfo-passwd.c
--- dovecot-0.99.7/src/auth/userinfo-passwd.c	2003-01-05 15:09:51.000000000 +0200
+++ dovecot-0.99.7p1/src/auth/userinfo-passwd.c	2003-01-21 09:39:28.000000000 +0200
@@ -37,8 +37,21 @@
 	int result;
 
 	pw = getpwnam(user);
-	if (pw == NULL || !IS_VALID_PASSWD(pw->pw_passwd))
+	if (pw == NULL) {
+		if (errno != 0)
+			i_error("getpwnam(%s) failed: %m", user);
+		else if (verbose)
+			i_info("passwd(%s): unknown user", user);
 		return FALSE;
+	}
+
+	if (!IS_VALID_PASSWD(pw->pw_passwd)) {
+		if (verbose) {
+			i_info("passwd(%s): invalid password field '%s'",
+			       user, pw->pw_passwd);
+		}
+		return FALSE;
+	}
 
 	/* check if the password is valid */
 	result = strcmp(mycrypt(password, pw->pw_passwd), pw->pw_passwd) == 0;
@@ -46,8 +59,11 @@
 	/* clear the passwords from memory */
 	safe_memset(pw->pw_passwd, 0, strlen(pw->pw_passwd));
 
-	if (!result)
+	if (!result) {
+		if (verbose)
+			i_info("passwd(%s): password mismatch", user);
 		return FALSE;
+	}
 
 	/* password ok, save the user info */
         passwd_fill_cookie_reply(pw, reply);
diff -ru dovecot-0.99.7/src/auth/userinfo-shadow.c dovecot-0.99.7p1/src/auth/userinfo-shadow.c
--- dovecot-0.99.7/src/auth/userinfo-shadow.c	2003-01-05 15:09:51.000000000 +0200
+++ dovecot-0.99.7p1/src/auth/userinfo-shadow.c	2003-01-21 09:39:28.000000000 +0200
@@ -23,8 +23,21 @@
 	int result;
 
 	spw = getspnam(user);
-	if (spw == NULL || !IS_VALID_PASSWD(spw->sp_pwdp))
+	if (spw == NULL) {
+		if (errno != 0)
+			i_error("getspnam(%s) failed: %m", user);
+		else if (verbose)
+			i_info("shadow(%s): unknown user", user);
 		return FALSE;
+	}
+
+	if (!IS_VALID_PASSWD(spw->sp_pwdp)) {
+		if (verbose) {
+			i_info("shadow(%s): invalid password field '%s'",
+			       user, spw->sp_pwdp);
+		}
+		return FALSE;
+	}
 
 	/* check if the password is valid */
 	result = strcmp(mycrypt(password, spw->sp_pwdp), spw->sp_pwdp) == 0;
@@ -32,13 +45,18 @@
 	/* clear the passwords from memory */
 	safe_memset(spw->sp_pwdp, 0, strlen(spw->sp_pwdp));
 
-	if (!result)
+	if (!result) {
+		if (verbose)
+			i_info("shadow(%s): password mismatch", user);
 		return FALSE;
+	}
 
 	/* password ok, save the user info */
 	pw = getpwnam(user);
-	if (pw == NULL)
+	if (pw == NULL) {
+		i_error("shadow(%s): getpwnam() failed: %m", user);
 		return FALSE;
+	}
 
         passwd_fill_cookie_reply(pw, reply);
 	return TRUE;
diff -ru dovecot-0.99.7/src/auth/userinfo-vpopmail.c dovecot-0.99.7p1/src/auth/userinfo-vpopmail.c
--- dovecot-0.99.7/src/auth/userinfo-vpopmail.c	2003-01-05 15:09:51.000000000 +0200
+++ dovecot-0.99.7p1/src/auth/userinfo-vpopmail.c	2003-01-21 09:39:28.000000000 +0200
@@ -14,8 +14,6 @@
 #include <vpopmail.h>
 #include <vauth.h>
 
-#define I_DEBUG(x) /* i_warning x */
-
 /* Limit user and domain to 80 chars each (+1 for \0). I wouldn't recommend
    raising this limit at least much, vpopmail is full of potential buffer
    overflows. */
@@ -36,7 +34,8 @@
 
 	if (parse_email(t_strdup_noconst(user), vpop_user, vpop_domain,
 			sizeof(vpop_user)-1) < 0) {
-		I_DEBUG(("vpopmail: parse_email(%s) failed", user));
+		if (verbose)
+			i_info("vpopmail(%s): parse_email() failed", user);
 		return FALSE;
 	}
 
@@ -44,19 +43,25 @@
 	   struct vqpasswd isn't really gid at all but just some flags... */
 	if (vget_assign(vpop_domain, NULL, 0,
 			&reply->uid, &reply->gid) == NULL) {
-		I_DEBUG(("vpopmail: vget_assign(%s) failed", vpop_domain));
+		if (verbose) {
+			i_info("vpopmail(%s): vget_assign(%s) failed",
+			       user, vpop_domain);
+		}
 		return FALSE;
 	}
 
 	vpw = vauth_getpw(vpop_user, vpop_domain);
 	if (vpw != NULL && (vpw->pw_dir == NULL || vpw->pw_dir[0] == '\0')) {
 		/* user's homedir doesn't exist yet, create it */
-		I_DEBUG(("vpopmail: pw_dir isn't set, creating"));
+		if (verbose) {
+			i_info("vpopmail(%s): pw_dir isn't set, creating",
+			       user);
+		}
 
 		if (make_user_dir(vpop_user, vpop_domain,
 				  reply->uid, reply->gid) == NULL) {
-			i_error("vpopmail: make_user_dir(%s, %s) failed",
-				vpop_user, vpop_domain);
+			i_error("vpopmail(%s): make_user_dir(%s, %s) failed",
+				user, vpop_user, vpop_domain);
 			return FALSE;
 		}
 
@@ -64,14 +69,16 @@
 	}
 
 	if (vpw == NULL) {
-		I_DEBUG(("vpopmail: vauth_getpw(%s, %s) failed",
-		       vpop_user, vpop_domain));
+		if (verbose) {
+			i_info("vpopmail(%s): vauth_getpw(%s, %s) failed",
+			       user, vpop_user, vpop_domain);
+		}
 		return FALSE;
 	}
 
 	if (vpw->pw_gid & NO_IMAP) {
-		I_DEBUG(("vpopmail: IMAP disabled for %s@%s",
-		       vpop_user, vpop_domain));
+		if (verbose)
+			i_info("vpopmail(%s): IMAP disabled", user);
 		return FALSE;
 	}
 
@@ -80,8 +87,8 @@
 	safe_memset(vpw->pw_passwd, 0, strlen(vpw->pw_passwd));
 
 	if (!result) {
-		I_DEBUG(("vpopmail: password mismatch for user %s@%s",
-		       vpop_user, vpop_domain));
+		if (verbose)
+			i_info("vpopmail(%s): password mismatch", user);
 		return FALSE;
 	}
 
diff -ru dovecot-0.99.7/src/master/auth-process.c dovecot-0.99.7p1/src/master/auth-process.c
--- dovecot-0.99.7/src/master/auth-process.c	2003-01-11 21:55:57.000000000 +0200
+++ dovecot-0.99.7p1/src/master/auth-process.c	2003-01-21 09:39:28.000000000 +0200
@@ -278,6 +278,8 @@
 
 	if (config->use_cyrus_sasl)
 		env_put("USE_CYRUS_SASL=1");
+	if (config->verbose)
+		env_put("VERBOSE=1");
 
 	restrict_process_size(config->process_size);
 
diff -ru dovecot-0.99.7/src/master/settings.c dovecot-0.99.7p1/src/master/settings.c
--- dovecot-0.99.7/src/master/settings.c	2003-01-05 17:19:50.000000000 +0200
+++ dovecot-0.99.7p1/src/master/settings.c	2003-01-21 09:39:28.000000000 +0200
@@ -417,6 +417,9 @@
 	if (strcmp(key, "auth_cyrus_sasl") == 0)
 		return get_bool(value, &auth->use_cyrus_sasl);
 
+	if (strcmp(key, "auth_verbose") == 0)
+		return get_bool(value, &auth->verbose);
+
 	if (strcmp(key, "auth_count") == 0) {
 		int num;
 
diff -ru dovecot-0.99.7/src/master/settings.h dovecot-0.99.7p1/src/master/settings.h
--- dovecot-0.99.7/src/master/settings.h	2003-01-05 17:19:50.000000000 +0200
+++ dovecot-0.99.7p1/src/master/settings.h	2003-01-21 09:39:28.000000000 +0200
@@ -71,7 +71,7 @@
 	char *user;
 	char *chroot;
 
-	int use_cyrus_sasl;
+	int use_cyrus_sasl, verbose;
 
 	unsigned int count;
 	unsigned int process_size;
