Index: lib/libpam/libpam/security/pam_mod_misc.h =================================================================== --- lib/libpam/libpam/security/pam_mod_misc.h +++ lib/libpam/libpam/security/pam_mod_misc.h @@ -37,6 +37,7 @@ * Common option names */ #define PAM_OPT_NULLOK "nullok" +#define PAM_OPT_EMPTYOK "emptyok" #define PAM_OPT_AUTH_AS_SELF "auth_as_self" #define PAM_OPT_ECHO_PASS "echo_pass" #define PAM_OPT_DEBUG "debug" Index: lib/libpam/modules/pam_unix/pam_unix.8 =================================================================== --- lib/libpam/modules/pam_unix/pam_unix.8 +++ lib/libpam/modules/pam_unix/pam_unix.8 @@ -116,6 +116,16 @@ option may cause .Nm to allow any user to log in with any password. +.It Cm emptyok +If the password database contains the password for the entity being +authenticated, but the password matches an empty string, +then this option will forgo password prompting, and +silently allow authentication to succeed. +.Pp +The difference between this and +.Cm nullok +is that it avoids prompting for password when the password is set +to an empty string, as opposed to not being set. .It Cm local_pass Use only the local password database, even if NIS is in use. This will cause an authentication failure if the system is configured Index: lib/libpam/modules/pam_unix/pam_unix.c =================================================================== --- lib/libpam/modules/pam_unix/pam_unix.c +++ lib/libpam/modules/pam_unix/pam_unix.c @@ -94,6 +94,7 @@ struct passwd *pwd; int retval; const char *pass, *user, *realpw, *prompt; + const char *emptypasswd = ""; if (openpam_get_option(pamh, PAM_OPT_AUTH_AS_SELF)) { user = getlogin(); @@ -116,6 +117,15 @@ PAM_LOG("Password is empty, using fake password"); realpw = "*"; } + /* + * Check whether the saved password hash matches the one + * generated from an empty password - as opposed to empty + * saved password hash, which is handled above. + */ + if (!(flags & PAM_DISALLOW_NULL_AUTHTOK) && + openpam_get_option(pamh, PAM_OPT_EMPTYOK) && + strcmp(crypt(emptypasswd, realpw), realpw) == 0) + return (PAM_SUCCESS); lc = login_getpwclass(pwd); } else { PAM_LOG("Doing dummy authentication");