Patch from Martin Schwenke <martin@meltin.net>

Index: Linux-PAM/modules/pam_unix/pam_unix_passwd.c
===================================================================
--- Linux-PAM/modules/pam_unix/pam_unix_passwd.c	(revision 289)
+++ Linux-PAM/modules/pam_unix/pam_unix_passwd.c	(working copy)
@@ -376,7 +376,7 @@
     struct passwd *tmpent = NULL;
     struct stat st;
     FILE *pwfile, *opwfile;
-    int err = 1;
+    int err = 1, found = 0;
     int oldmask;
 
     oldmask = umask(077);
@@ -423,6 +423,7 @@
 
 	    tmpent->pw_passwd = assigned_passwd.charp;
 	    err = 0;
+	    found = 1;
 	}
 	if (putpwent(tmpent, pwfile)) {
 	    D(("error writing entry to password file: %s\n", strerror(errno)));
@@ -446,7 +447,7 @@
     }
 
     unlink(PW_TMPFILE);
-    return PAM_AUTHTOK_ERR;
+    return found ? PAM_AUTHTOK_ERR : PAM_USER_UNKNOWN;
 }
 
 static int _update_shadow(pam_handle_t *pamh, const char *forwho, char *towhat)
@@ -454,7 +455,7 @@
     struct spwd *spwdent = NULL, *stmpent = NULL;
     struct stat st;
     FILE *pwfile, *opwfile;
-    int err = 1;
+    int err = 1, found = 0;
     int oldmask;
 
     spwdent = getspnam(forwho);
@@ -501,6 +502,7 @@
 	    stmpent->sp_pwdp = towhat;
 	    stmpent->sp_lstchg = time(NULL) / (60 * 60 * 24);
 	    err = 0;
+	    found = 1;
 	    D(("Set password %s for %s", stmpent->sp_pwdp, forwho));
 	}
 
@@ -527,7 +529,7 @@
     }
 
     unlink(SH_TMPFILE);
-    return PAM_AUTHTOK_ERR;
+    return found ? PAM_AUTHTOK_ERR : PAM_USER_UNKNOWN;
 }
 
 static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
@@ -639,7 +641,7 @@
 	return retval;
 }
 
-static int _unix_verify_shadow(const char *user, unsigned int ctrl)
+static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned int ctrl)
 {
 	struct passwd *pwd = NULL;	/* Password and shadow password */
 	struct spwd *spwdent = NULL;	/* file entries for the user */
@@ -647,7 +649,7 @@
 	int retval = PAM_SUCCESS;
 
 	/* UNIX passwords area */
-	pwd = getpwnam(user);	/* Get password file entry... */
+	_unix_getpwnam(pamh, user, 1, 0, &pwd);	/* Get password *file* entry... */
 	if (pwd == NULL)
 		return PAM_AUTHINFO_UNAVAIL;	/* We don't need to do the rest... */
 
@@ -908,7 +910,7 @@
 			_log_err(LOG_CRIT, pamh,
 			         "failed to set PAM_OLDAUTHTOK");
 		}
-		retval = _unix_verify_shadow(user, ctrl);
+		retval = _unix_verify_shadow(pamh, user, ctrl);
 		if (retval == PAM_AUTHTOK_ERR) {
 			if (off(UNIX__IAMROOT, ctrl))
 				_make_remark(pamh, ctrl, PAM_ERROR_MSG,
@@ -1033,7 +1035,7 @@
 			}
 		}
 
-		retval = _unix_verify_shadow(user, ctrl);
+		retval = _unix_verify_shadow(pamh, user, ctrl);
 		if (retval != PAM_SUCCESS) {
 			_log_err(LOG_NOTICE, pamh, "user not authenticated 2");
 #ifdef USE_LCKPWDF
