Index: shadow-4.2.1/src/useradd.c =================================================================== --- shadow-4.2.1.orig/src/useradd.c +++ shadow-4.2.1/src/useradd.c @@ -51,7 +51,9 @@ #include #include #include +#include #include +#include #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) +{ + static 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 processe running! */ + /* NOTREACHED */ + break; + default: /* parent */ + if (waitpid(childpid, &status, 0) == -1 || !WIFEXITED(status) || WEXITSTATUS(status) != 0) + failed = 3; + 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 * @@ -2286,6 +2335,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) {