From: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Date: Sat, 14 May 2022 02:52:50 +0800
Subject: _login_FAILLOG_ENAB

Goal: Re-enable logging and displaying failures on login when login is
      compiled with PAM and when FAILLOG_ENAB is set to yes. And create the
      faillog file if it does not exist on postinst (as on Woody).
Depends: 008_login_more_LOG_UNKFAIL_ENAB
Fixes: #192849
Note: It could be removed if pam_tally could report the number of failures
      preceding a successful login.
---
 lib/getdef.c |  1 +
 src/login.c  | 19 ++++++++++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/lib/getdef.c b/lib/getdef.c
index e639593..9ce3cfa 100644
--- a/lib/getdef.c
+++ b/lib/getdef.c
@@ -89,6 +89,7 @@ static struct itemdef def_table[] = {
 	{"ENV_SUPATH", NULL},
 	{"ERASECHAR", NULL},
 	{"FAIL_DELAY", NULL},
+	{"FAILLOG_ENAB", NULL},
 	{"FAKE_SHELL", NULL},
 	{"FTMP_FILE", NULL},
 	{"GID_MAX", NULL},
diff --git a/src/login.c b/src/login.c
index ffe65f7..f56dafb 100644
--- a/src/login.c
+++ b/src/login.c
@@ -136,9 +136,9 @@ static void update_utmp (const char *user,
 #endif
 			);
 
-#ifndef USE_PAM
 static struct faillog faillog;
 
+#ifndef USE_PAM
 static void bad_time_notify (void);
 static void check_nologin (bool login_to_root);
 #else
@@ -809,6 +809,9 @@ int main (int argc, char **argv)
 				SYSLOG ((LOG_NOTICE,
 				         "TOO MANY LOGIN TRIES (%u)%s FOR '%s'",
 				         failcount, fromhost, failent_user));
+				if ((NULL != pwd) && getdef_bool("FAILLOG_ENAB")) {
+					failure (pwd->pw_uid, tty, &faillog);
+				}
 				fprintf (stderr,
 				         _("Maximum number of tries exceeded (%u)\n"),
 				         failcount);
@@ -826,6 +829,14 @@ int main (int argc, char **argv)
 				         pam_strerror (pamh, retcode)));
 				failed = true;
 			}
+			if (   (NULL != pwd)
+			    && getdef_bool("FAILLOG_ENAB")
+			    && ! failcheck (pwd->pw_uid, &faillog, failed)) {
+				SYSLOG((LOG_CRIT,
+				        "exceeded failure limit for `%s' %s",
+				        failent_user, fromhost));
+				failed = 1;
+			}
 
 			if (!failed) {
 				break;
@@ -849,6 +860,10 @@ int main (int argc, char **argv)
 			(void) puts ("");
 			(void) puts (_("Login incorrect"));
 
+			if ((NULL != pwd) && getdef_bool("FAILLOG_ENAB")) {
+				failure (pwd->pw_uid, tty, &faillog);
+			}
+
 			if (getdef_str("FTMP_FILE") != NULL) {
 #ifdef USE_UTMPX
 				struct utmpx *failent =
@@ -1305,6 +1320,7 @@ int main (int argc, char **argv)
 		 */
 #ifndef USE_PAM
 		motd ();	/* print the message of the day */
+#endif
 		if (   getdef_bool ("FAILLOG_ENAB")
 		    && (0 != faillog.fail_cnt)) {
 			failprint (&faillog);
@@ -1317,6 +1333,7 @@ int main (int argc, char **argv)
 				         username, (int) faillog.fail_cnt));
 			}
 		}
+#ifndef USE_PAM
 		if (   getdef_bool ("LASTLOG_ENAB")
 		    && pwd->pw_uid <= (uid_t) getdef_ulong ("LASTLOG_UID_MAX", 0xFFFFFFFFUL)
 		    && (ll.ll_time != 0)) {
