From 2a1462d9f6a117cf1a5ae531d36143bd0a55d533 Mon Sep 17 00:00:00 2001
From: Joachim Wiberg <troglobit@gmail.com>
Date: Wed, 5 Jul 2023 23:48:14 +0200
Subject: [PATCH 2/2] login: add support for shadow passwords
Organization: Addiva Elektronik

login, on fallback from PAM, or when PAM support is not enabled, checks
pw->pw_passwd for locked ("!") or passwordless ("*") accounts.  However,
on systems with shadow passwords the first character will always be "x".

This patch adds shadow password support from the passwd tool, letting
the user end up in "Login incorrect" rather than the "login: bad salt"
case, which could be used by an attacker to guess the state of accounts.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
---
 loginutils/login.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/loginutils/login.c b/loginutils/login.c
index b02be2176..0e7f20844 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -345,6 +345,11 @@ int login_main(int argc UNUSED_PARAM, char **argv)
 #endif
 #if ENABLE_LOGIN_SESSION_AS_CHILD
 	pid_t child_pid;
+#endif
+#if ENABLE_FEATURE_SHADOWPASSWDS
+	/* Using _r function to avoid pulling in static buffers */
+	struct spwd spw, *result = NULL;
+	char buffer[256];
 #endif
 	IF_FEATURE_UTMP(pid_t my_pid;)
 
@@ -493,6 +498,16 @@ int login_main(int argc UNUSED_PARAM, char **argv)
 			goto fake_it;
 		}
 
+#if ENABLE_FEATURE_SHADOWPASSWDS
+		if (getspnam_r(pw->pw_name, &spw, buffer, sizeof(buffer), &result)
+		    || !result || strcmp(result->sp_namp, pw->pw_name)) {
+			strcpy(username, "UNKNOWN");
+			goto fake_it;
+		} else {
+			pw->pw_passwd = result->sp_pwdp;
+		}
+#endif
+
 		if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*')
 			goto auth_failed;
 
-- 
2.34.1

