pam: add option to not prompt for password if it's set to empty

Add a new option to pam_unix(8), "emptyok", which makes it not prompt
for password, if it's set to an empty one.  It is similar to "nullok",
which makes it not prompt for password if the hash itself is empty.

Reviewed By:	markj
Sponsored By:	NetApp, Inc.
Sponsored By:	Klara, Inc.
Differential Revision:	https://reviews.freebsd.org/D27569
This commit is contained in:
Edward Tomasz Napierala 2021-04-03 13:01:45 +01:00
parent ab899f8937
commit bfd8b9b826
3 changed files with 22 additions and 1 deletions

View File

@ -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"

View File

@ -34,7 +34,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 20, 2009
.Dd April 3, 2020
.Dt PAM_UNIX 8
.Os
.Sh NAME
@ -116,6 +116,16 @@ privileges), the
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

View File

@ -94,6 +94,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags __unused,
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_sm_authenticate(pam_handle_t *pamh, int flags __unused,
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");