File shadow-4.2.1-reset-tallylog.patch of Package shadow.8444

diff --git a/src/useradd.c b/src/useradd.c
index 95e8ee7e..5fb1f91a 100644
--- a/src/useradd.c
+++ b/src/useradd.c
@@ -51,7 +51,9 @@
 #include <string.h>
 #include <sys/stat.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <time.h>
+#include <unistd.h>
 #include "chkname.h"
 #include "defines.h"
 #include "faillog.h"
@@ -213,6 +215,7 @@ static void open_files (void);
 static void open_shadow (void);
 static void faillog_reset (uid_t);
 static void lastlog_reset (uid_t);
+static void tallylog_reset (char *);
 static void usr_update (void);
 static void create_home (void);
 static void create_mail (void);
@@ -1789,6 +1792,52 @@ static void lastlog_reset (uid_t uid)
 	}
 }
 
+static void tallylog_reset (char *user_name)
+{
+	const char pam_tally2[] = "/sbin/pam_tally2";
+	const char *pname;
+	pid_t childpid;
+	int failed;
+	int status;
+
+	if (access(pam_tally2, X_OK) == -1)
+		return;
+
+	failed = 0;
+	switch (childpid = fork())
+	{
+	case -1: /* error */
+		failed = 1;
+		break;
+	case 0: /* child */
+		pname = strrchr(pam_tally2, '/');
+		if (pname == NULL)
+			pname = pam_tally2;
+		else
+			pname++;        /* Skip the '/' */
+		execl(pam_tally2, pname, "--user", user_name, "--reset", "--quiet", NULL);
+		/* If we come here, something has gone terribly wrong */
+		perror(pam_tally2);
+		exit(42);       /* don't continue, we now have 2 processes running! */
+		/* NOTREACHED */
+		break;
+	default: /* parent */
+		if (waitpid(childpid, &status, 0) == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0)
+			failed = 1;
+		break;
+	}
+
+	if (failed)
+	{
+		fprintf (stderr,
+		         _("%s: failed to reset the tallylog entry of user \"%s\"\n"),
+		         Prog, user_name);
+		SYSLOG ((LOG_WARN, "failed to reset the tallylog entry of user \"%s\"", user_name));
+	}
+
+	return;
+}
+
 /*
  * usr_update - create the user entries
  *
@@ -2231,6 +2280,15 @@ int main (int argc, char **argv)
 
 	close_files ();
 
+	/*
+	 * tallylog_reset needs to be able to lookup
+	 * a valid existing user name,
+	 * so we canot call it before close_files()
+	 */
+	if (!lflg && getpwuid (user_id) != NULL) {
+		tallylog_reset (user_name);
+	}
+
 #ifdef WITH_SELINUX
 	if (Zflg) {
 		if (set_seuser (user_name, user_selinux) != 0) {
openSUSE Build Service is sponsored by