diff --git a/ChangeLog b/ChangeLog index ddffb795..45de7709 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,15 @@ 2009-04-04 Nicolas François - * src/chage.c: When no shadow entry exist, thedefault sp_lstchg + * libmisc/pwd2spwd.c, src/chpasswd.c, src/newusers.c, + src/passwd.c, src/pwck.c, src/pwconv.c, src/useradd.c, + src/usermod.c: On Jan 01, 1970, do not set the sp_lstchg field to + 0 (which means that the password shall be changed during the next + login), but use -1 (password aging disabled). + * src/passwd.c: Do not check sp_min if sp_lstchg is null or -1. + +2009-04-04 Nicolas François + + * src/chage.c: When no shadow entry exist, the default sp_lstchg value should be -1 (no aging) rather than 0 (password must be changed). * src/chage.c: For password expiration and inactivity, indicate diff --git a/libmisc/pwd2spwd.c b/libmisc/pwd2spwd.c index 1c41513b..a3d8cd2b 100644 --- a/libmisc/pwd2spwd.c +++ b/libmisc/pwd2spwd.c @@ -65,6 +65,11 @@ struct spwd *pwd_to_spwd (const struct passwd *pw) sp.sp_min = 0; sp.sp_max = (10000L * DAY) / SCALE; sp.sp_lstchg = (long) time ((time_t *) 0) / SCALE; + if (0 == sp.sp_lstchg) { + /* Better disable aging than requiring a password + * change */ + sp.sp_lstchg = -1; + } } /* diff --git a/src/chpasswd.c b/src/chpasswd.c index 697c9fc6..93bf935a 100644 --- a/src/chpasswd.c +++ b/src/chpasswd.c @@ -373,7 +373,6 @@ int main (int argc, char **argv) struct passwd newpw; int errors = 0; int line = 0; - long now = (long) time ((time_t *)NULL) / SCALE; Prog = Basename (argv[0]); @@ -478,7 +477,12 @@ int main (int argc, char **argv) if (NULL != sp) { newsp = *sp; newsp.sp_pwdp = cp; - newsp.sp_lstchg = now; + newsp.sp_lstchg = (long) time ((time_t *)NULL) / SCALE; + if (0 == newsp.sp_lstchg) { + /* Better disable aging than requiring a + * password change */ + newssp.sp_lstchg = -1; + } } else { newpw = *pw; newpw.pw_passwd = cp; diff --git a/src/newusers.c b/src/newusers.c index 5ea71b8c..de5c5eec 100644 --- a/src/newusers.c +++ b/src/newusers.c @@ -452,6 +452,10 @@ static int add_passwd (struct passwd *pwd, const char *password) spent.sp_pwdp = pw_encrypt (password, salt); } spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE; + if (0 == spent.sp_lstchg) { + /* Better disable aging than requiring a password change */ + spent.sp_lstchg = -1; + } spent.sp_min = getdef_num ("PASS_MIN_DAYS", 0); /* 10000 is infinity this week */ spent.sp_max = getdef_num ("PASS_MAX_DAYS", 10000); diff --git a/src/passwd.c b/src/passwd.c index 31adc48d..5e51efa5 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -385,11 +385,13 @@ static void check_password (const struct passwd *pw, const struct spwd *sp) * changed. Passwords which have been inactive too long cannot be * changed. */ - if (sp->sp_pwdp[0] == '!' || exp_status > 1 || - (sp->sp_max >= 0 && sp->sp_min > sp->sp_max)) { + if ( (sp->sp_pwdp[0] == '!') + || (exp_status > 1) + || ( (sp->sp_max >= 0) + && (sp->sp_min > sp->sp_max))) { fprintf (stderr, - _("The password for %s cannot be changed.\n"), - sp->sp_namp); + _("The password for %s cannot be changed.\n"), + sp->sp_namp); SYSLOG ((LOG_WARN, "password locked for '%s'", sp->sp_namp)); closelog (); exit (E_NOPERM); @@ -398,17 +400,18 @@ static void check_password (const struct passwd *pw, const struct spwd *sp) /* * Passwords may only be changed after sp_min time is up. */ - last = sp->sp_lstchg * SCALE; - ok = last + (sp->sp_min > 0 ? sp->sp_min * SCALE : 0); + if (sp->sp_lstchg > 0) { + last = sp->sp_lstchg * SCALE; + ok = last + (sp->sp_min > 0 ? sp->sp_min * SCALE : 0); - if (now < ok) { - fprintf (stderr, - _ - ("The password for %s cannot be changed yet.\n"), - pw->pw_name); - SYSLOG ((LOG_WARN, "now < minimum age for '%s'", pw->pw_name)); - closelog (); - exit (E_NOPERM); + if (now < ok) { + fprintf (stderr, + _("The password for %s cannot be changed yet.\n"), + pw->pw_name); + SYSLOG ((LOG_WARN, "now < minimum age for '%s'", pw->pw_name)); + closelog (); + exit (E_NOPERM); + } } } @@ -633,6 +636,11 @@ static void update_shadow (void) } if (do_update_age) { nsp->sp_lstchg = (long) time ((time_t *) 0) / SCALE; + if (0 == nsp->sp_lstchg) { + /* Better disable aging than requiring a password + * change */ + nsp->sp_lstchg = -1; + } } /* @@ -640,8 +648,9 @@ static void update_shadow (void) * 2.x passwd -f. Solaris 2.x seems to do the same thing (set * sp_lstchg to 0). */ - if (eflg) + if (eflg) { nsp->sp_lstchg = 0; + } if (spw_update (nsp) == 0) { fprintf (stderr, diff --git a/src/pwck.c b/src/pwck.c index 81b2b7e5..2483907d 100644 --- a/src/pwck.c +++ b/src/pwck.c @@ -473,6 +473,12 @@ static void check_pw_file (int *errors, bool *changed) sp.sp_expire = -1; sp.sp_flag = SHADOW_SP_FLAG_UNSET; sp.sp_lstchg = (long) time ((time_t *) 0) / SCALE; + if (0 == sp.sp_lstchg) { + /* Better disable aging than + * requiring a password change + */ + sp.sp_lstchg = -1; + } *changed = true; if (spw_update (&sp) == 0) { diff --git a/src/pwconv.c b/src/pwconv.c index 262343d3..a97bd65e 100644 --- a/src/pwconv.c +++ b/src/pwconv.c @@ -203,6 +203,11 @@ int main (int argc, char **argv) } spent.sp_pwdp = pw->pw_passwd; spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE; + if (0 == spent.sp_lstchg) { + /* Better disable aging than requiring a password + * change */ + spent.sp_lstchg = -1; + } if (spw_update (&spent) == 0) { fprintf (stderr, _("%s: failed to prepare the new %s entry '%s'\n"), diff --git a/src/useradd.c b/src/useradd.c index d14767d0..8ae84249 100644 --- a/src/useradd.c +++ b/src/useradd.c @@ -766,6 +766,10 @@ static void new_spent (struct spwd *spent) spent->sp_namp = (char *) user_name; spent->sp_pwdp = (char *) user_pass; spent->sp_lstchg = (long) time ((time_t *) 0) / SCALE; + if (0 == spent->sp_lstchg) { + /* Better disable aging than requiring a password change */ + spent->sp_lstchg = -1; + } if (!rflg) { spent->sp_min = scale_age (getdef_num ("PASS_MIN_DAYS", -1)); spent->sp_max = scale_age (getdef_num ("PASS_MAX_DAYS", -1)); diff --git a/src/usermod.c b/src/usermod.c index cb4d803a..e76f510a 100644 --- a/src/usermod.c +++ b/src/usermod.c @@ -521,6 +521,11 @@ static void new_spent (struct spwd *spent) spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp); if (pflg) { spent->sp_lstchg = (long) time ((time_t *) 0) / SCALE; + if (0 == spent->sp_lstchg) { + /* Better disable aging than requiring a password + * change */ + spent->sp_lstchg = -1; + } } }