diff -u shadow-4.1.1/debian/changelog shadow-4.1.1/debian/changelog --- shadow-4.1.1/debian/changelog +++ shadow-4.1.1/debian/changelog @@ -1,3 +1,15 @@ +shadow (1:4.1.1-6ubuntu4) jaunty; urgency=low + + * debian/patches/593_omit_lastchange_field_if_clock_is_misset (LP: #349504) + - If the system clock is set to Jan 01, 1970, and a new user is created + the last changed field gets set to 0, which tells login that the + password is expired and must be changed. During installation, + this can cause autologin to fail. Having the clock set to 01/01/1970 + on a fresh install is common on the ARM architecture, so this is a high + priority bug since its likely to affect most ARM users on first install + + -- Michael Casadevall Thu, 02 Apr 2009 14:05:31 -0400 + shadow (1:4.1.1-6ubuntu3) jaunty; urgency=low [ Bryan McLellan ] diff -u shadow-4.1.1/debian/patches/series shadow-4.1.1/debian/patches/series --- shadow-4.1.1/debian/patches/series +++ shadow-4.1.1/debian/patches/series @@ -40,0 +41 @@ +593_omit_lastchange_field_if_clock_is_misset only in patch2: unchanged: --- shadow-4.1.1.orig/debian/patches/593_omit_lastchange_field_if_clock_is_misset +++ shadow-4.1.1/debian/patches/593_omit_lastchange_field_if_clock_is_misset @@ -0,0 +1,223 @@ +Index: shadow-4.1.1/src/useradd.c +=================================================================== +--- shadow-4.1.1.orig/src/useradd.c 2009-04-02 21:09:54.260892797 -0400 ++++ shadow-4.1.1/src/useradd.c 2009-04-02 21:09:54.580852116 -0400 +@@ -710,6 +710,29 @@ + spent->sp_namp = (char *) user_name; + spent->sp_pwdp = (char *) user_pass; + spent->sp_lstchg = time ((time_t *) 0) / SCALE; ++ ++ /* ++ * If the system clock is set to Jan-01-1970, the lastchg field will ++ * come out as zero (which is the value used when a password is expired ++ * with passwd -e. In these cases, replace 0 with -1 to omit the field ++ * since whatever value we would come up would be wrong anyway. ++ */ ++ ++ if (spent->sp_lstchg == 0) ++ { ++ if (spent->sp_pwdp != "!") { ++ /* If we're setting a password, display a warning that password aging will be disabled */ ++ fprintf (stderr, ++ _ ++ ("%s: warning: system clock set to January 01, 1970.\n" ++ "The last changed field will be omitted from /etc/shadow.\n" ++ "Password aging will be disabled on this account until a new password is set with the system clock properly set.\n" ), ++ Prog); ++ } ++ ++ 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)); +Index: shadow-4.1.1/src/chpasswd.c +=================================================================== +--- shadow-4.1.1.orig/src/chpasswd.c 2009-04-02 21:09:54.568871823 -0400 ++++ shadow-4.1.1/src/chpasswd.c 2009-04-02 21:09:54.580852116 -0400 +@@ -341,6 +341,15 @@ + + process_flags (argc, argv); + ++ if (now == 0) { ++ fprintf (stderr, ++ _ ++ ("%s: warning: system clock set to January 01, 1970.\n" ++ "The last changed field will be omitted from /etc/shadow.\n" ++ "Password aging will be disabled on this account until a new password is set with the system clock properly set.\n" ), ++ Prog); ++ } ++ + if (!use_stdout) { + check_perms (); + +@@ -439,7 +448,18 @@ + if (NULL != sp) { + newsp = *sp; + newsp.sp_pwdp = cp; ++ ++ /* ++ * If the system clock is set to Jan-01-1970, the lastchg field will ++ * come out as zero (which is the value used when a password is expired ++ * with passwd -e. In these cases, replace 0 with -1 to omit the field ++ * since whatever value we would come up would be wrong anyway. ++ */ ++ + newsp.sp_lstchg = now; ++ if (newsp.sp_lstchg == 0) ++ newsp.sp_lstchg = -1; ++ + } else { + newpw = *pw; + newpw.pw_passwd = cp; +Index: shadow-4.1.1/src/passwd.c +=================================================================== +--- shadow-4.1.1.orig/src/passwd.c 2009-04-02 21:09:54.512870154 -0400 ++++ shadow-4.1.1/src/passwd.c 2009-04-02 21:09:54.580852116 -0400 +@@ -572,6 +572,24 @@ + nsp->sp_lstchg = time ((time_t *) 0) / SCALE; + + /* ++ * If the system clock is set to Jan-01-1970, the lastchg field will ++ * come out as zero (which is the value used when a password is expired ++ * with passwd -e. In these cases, replace 0 with -1 to omit the field ++ * since whatever value we would come up would be wrong anyway. ++ */ ++ ++ if (nsp->sp_lstchg == 0) { ++ fprintf (stderr, ++ _ ++ ("%s: warning: system clock set to January 01, 1970.\n" ++ "The last changed field will be omitted from /etc/shadow.\n" ++ "Password aging will be disabled on this account until a new password is set with the system clock properly set.\n" ), ++ Prog); ++ ++ nsp->sp_lstchg = -1; ++ } ++ ++ /* + * Force change on next login, like SunOS 4.x passwd -e or Solaris + * 2.x passwd -f. Solaris 2.x seems to do the same thing (set + * sp_lstchg to 0). +Index: shadow-4.1.1/libmisc/pwd2spwd.c +=================================================================== +--- shadow-4.1.1.orig/libmisc/pwd2spwd.c 2009-04-02 21:09:48.284851709 -0400 ++++ shadow-4.1.1/libmisc/pwd2spwd.c 2009-04-02 21:09:54.580852116 -0400 +@@ -62,6 +62,10 @@ + sp.sp_min = 0; + sp.sp_max = (10000L * DAY) / SCALE; + sp.sp_lstchg = time ((time_t *) 0) / SCALE; ++ ++ if (sp.sp_lstchg == 0) { ++ sp.sp_lstchg = -1; ++ } + } + + /* +Index: shadow-4.1.1/src/newusers.c +=================================================================== +--- shadow-4.1.1.orig/src/newusers.c 2009-04-02 21:09:54.476851191 -0400 ++++ shadow-4.1.1/src/newusers.c 2009-04-02 21:09:54.580852116 -0400 +@@ -65,6 +65,7 @@ + static int cflg = 0; + static int rflg = 0; /* create a system account */ + static int sflg = 0; ++static long now = 0; + + static char *crypt_method = NULL; + static long sha_rounds = 5000; +@@ -419,7 +420,18 @@ + const char *salt = crypt_make_salt (crypt_method, crypt_arg); + spent.sp_pwdp = pw_encrypt (password, salt); + } +- spent.sp_lstchg = time ((time_t *) 0) / SCALE; ++ spent.sp_lstchg = now; ++ ++ /* ++ * If the system clock is set to Jan-01-1970, the lastchg field will ++ * come out as zero (which is the value used when a password is expired ++ * with passwd -e. In these cases, replace 0 with -1 to omit the field ++ * since whatever value we would come up would be wrong anyway. ++ */ ++ ++ if (spent.sp_lstchg == 0) ++ 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); +@@ -668,6 +680,8 @@ + uid_t uid; + gid_t gid; + ++ now = time ((time_t *) 0) / SCALE; ++ + Prog = Basename (argv[0]); + + setlocale (LC_ALL, ""); +@@ -678,6 +692,15 @@ + + check_perms (); + ++ if (now == 0) { ++ fprintf (stderr, ++ _ ++ ("%s: warning: system clock set to January 01, 1970.\n" ++ "The last changed field will be omitted from /etc/shadow.\n" ++ "Password aging will be disabled on this account until a new password is set with the system clock properly set.\n" ), ++ Prog); ++ } ++ + is_shadow = spw_file_present (); + + #ifdef SHADOWGRP +Index: shadow-4.1.1/src/pwconv.c +=================================================================== +--- shadow-4.1.1.orig/src/pwconv.c 2009-04-02 21:09:48.244903334 -0400 ++++ shadow-4.1.1/src/pwconv.c 2009-04-02 21:09:54.584850879 -0400 +@@ -79,6 +79,7 @@ + const struct spwd *sp; + struct spwd spent; + char *Prog = argv[0]; ++ long now = time ((time_t *) 0) / (24L * 3600L); + + setlocale (LC_ALL, ""); + bindtextdomain (PACKAGE, LOCALEDIR); +@@ -104,6 +105,15 @@ + fail_exit (E_FAILURE); + } + ++ if (now == 0) { ++ fprintf (stderr, ++ _ ++ ("%s: warning: system clock set to January 01, 1970.\n" ++ "The last changed field will be omitted from /etc/shadow.\n" ++ "Password aging will be disabled on this account until a new password is set with the system clock properly set.\n" ), ++ Prog); ++ } ++ + /* + * Remove /etc/shadow entries for users not in /etc/passwd. + */ +@@ -149,7 +159,19 @@ + spent.sp_flag = -1; + } + spent.sp_pwdp = pw->pw_passwd; +- spent.sp_lstchg = time ((time_t *) 0) / (24L * 3600L); ++ spent.sp_lstchg = now; ++ ++ /* ++ * If the system clock is set to Jan-01-1970, the lastchg field will ++ * come out as zero (which is the value used when a password is expired ++ * with passwd -e. In these cases, replace 0 with -1 to omit the field ++ * since whatever value we would come up would be wrong anyway. ++ */ ++ ++ if (spent.sp_lstchg == 0) { ++ spent.sp_lstchg = -1; ++ } ++ + if (!spw_update (&spent)) { + fprintf (stderr, + _