Skip to content

Remove password aging#1432

Draft
alejandro-colomar wants to merge 25 commits intoshadow-maint:masterfrom
alejandro-colomar:expiry
Draft

Remove password aging#1432
alejandro-colomar wants to merge 25 commits intoshadow-maint:masterfrom
alejandro-colomar:expiry

Conversation

@alejandro-colomar
Copy link
Copy Markdown
Collaborator

@alejandro-colomar alejandro-colomar commented Dec 15, 2025


I intend to remove it in 4.21, and deprecate in 4.19.

Passwords should never expire. It has been proved to decrease password safety.

The following features and/or programs will be deprecated in 4.19:

  • expiry(1) // To be removed in 4.20
  • chage(1):
    • -I,--inactive (also the interactive version)
    • -m,--mindays (also the interactive version) // To be removed in 4.20
    • -M,--maxdays (also the interactive version)
    • -W,--warndays (also the interactive version)
  • passwd(1):
    • -k,--keep-tokens
    • -n,--mindays // To be removed in 4.20
    • -x,--maxdays
    • -i,--inactive
    • -w,--warndays
  • useradd(8):
    • -f,--inactive
  • usermod(8):
    • -f,--inactive
  • login.defs(5):
    • PASS_MIN_DAYS // To be removed in 4.20
    • PASS_MAX_DAYS // Remove it from the default file in 4.20
    • PASS_WARN_AGE // Remove it from the default file in 4.20
  • /etc/default/useradd:
    • INACTIVE
  • shadow(5):
    • sp_lstchg: Restrict to just the values 0 and empty.
    • sp_min // To be ignored in 4.20
    • sp_max
    • sp_warn
    • sp_inact

Distros should make sure to remove those 3 values from login.defs(5) ASAP. That will make sure that the transition from 4.20 to 4.21 will be smooth. These programs will fail if such a configuration is specified in 4.21.

Cc: @stoeckmann , @thesamesam , @floppym , @jubalh , @ikerexxe , @zeha , @hallyn


Here are some statistics of the PR:

$ COLUMNS=999 git diff --stat master..HEAD \
| grep '^ [^ ]' \
| tr / ' ' \
| awk '{print $1}' \
| sort \
| uniq \
| while read -r f; do
        echo $f;
        git diff --stat master..HEAD -- $f \
        | tail -n1;
done;
1533
configure.ac
 1 file changed, 3 deletions(-)
doc
 1 file changed, 3 insertions(+), 8 deletions(-)
etc
 1 file changed, 6 deletions(-)
lib
 10 files changed, 18 insertions(+), 220 deletions(-)
man
 35 files changed, 6 insertions(+), 1371 deletions(-)
po
 1 file changed, 2 deletions(-)
src
 12 files changed, 54 insertions(+), 1432 deletions(-)
tests
 1472 files changed, 18 insertions(+), 32517 deletions(-)

Here's what NIST and Microsoft say about this:

NIST
   NIST SP 800-63-3
       In 2017-06, NIST (National Institute of Standards and Technology)
       published NIST SP 800-63-3 <https://pages.nist.gov/800-63-3/> (Digital
       Identity Guidelines), which —among other documents— contained
       NIST SP 800-63B <https://pages.nist.gov/800-63-3/sp800-63b.html>
       (Authentication and Lifecycle Management).

       This 3rd revision of NIST SP 800-63 superseded NIST SP 800-63-2
       <https://csrc.nist.gov/pubs/sp/800/63/2/final> (Electronic
       Authentication Guideline), from 2013-08, which was withdrawn in
       2017-06-22.

       NIST SP 800-63B recommended in §5.1.1.2
       <https://pages.nist.gov/800-63-3/sp800-63b.html#memsecretver>
       (Memorized Secret Verifiers), paragraph 9, that passwords should not
       expire periodically.

              Verifiers SHOULD NOT require memorized secrets to be changed
              arbitrarily (e.g., periodically).  However, verifiers SHALL
              force a change if there is evidence of compromise of the
              authenticator.

       NIST SP 800-63-3 was amended in 2020-03-02, but didn't change this
       recommendation.

   FAQ
       In 2017-07, NIST published a FAQ page
       <https://pages.nist.gov/800-63-FAQ/> clarifying doubts about
       NIST SP 800-63.

       In 2018-04-30, an entry clarifying §5.1.1.2 was added
       <https://github.com/usnistgov/800-63-FAQ/commit/9a87d495088d>.

       That entry is currently numbered as B05
       <https://pages.nist.gov/800-63-FAQ/#q-b05> and contains the following
       text.

              Q-B05: Is password expiration no longer recommended?

              A-B05: SP 800-63B Section 5.1.1.2 paragraph 9 states:

                            “Verifiers SHOULD NOT require memorized secrets to
                            be changed arbitrarily (e.g., periodically).
                            However, verifiers SHALL force a change if there
                            is evidence of compromise of the authenticator.”

                     Users tend to choose weaker memorized secrets when they
                     know that they will have to change them in the near
                     future.  When those changes do occur, they often select a
                     secret that is similar to their old memorized secret by
                     applying a set of common transformations such as
                     increasing a number in the password.  This practice
                     provides a false sense of security if any of the previous
                     secrets has been compromised since attackers can apply
                     these same common transformations.  But if there is
                     evidence that the memorized secret has been compromised,
                     such as by a breach of the verifier’s hashed password
                     database or observed fraudulent activity, subscribers
                     should be required to change their memorized secrets.
                     However, this event-based change should occur rarely, so
                     that they are less motivated to choose a weak secret with
                     the knowledge that it will only be used for a limited
                     period of time.

   NIST SP 800-63-4
       In 2025-07, NIST published a new revision of the Digital Identity
       Guidelines: NIST SP 800-63-4 <https://pages.nist.gov/800-63-4/>, which
       —among other documents— contains NIST SP 800-63B-4
       <https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-63B-4.pdf>
       (Authentication and Authenticator Management).

       This 4th revision of NIST SP 800-63 superseded NIST SP 800-63-3
       <https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-63-3.pdf>,
       which was withdrawn in 2025-08-01.

       NIST SP 800-63B-4 is more strict than NIST SP 800-63B-3 regarding
       password expiration, and in §3.1.1.2
       <https://pages.nist.gov/800-63-4/sp800-63b.html#passwordver>, prohibits
       periodic password expiration.

              6.  Verifiers and CSPs SHALL NOT require subscribers to change
                  passwords periodically.  However, verifiers SHALL force a
                  change if there is evidence that the authenticator has been
                  compromised.

Microsoft
       Some corporations have changed their security policies similarly.

       In 2019, Microsoft released version v1903 of Windows 10.  With it, it
       also published the Security baseline (FINAL) for Windows 10 v1903 and
       Windows Server v1903
       <https://learn.microsoft.com/en-us/archive/blogs/secguide/security-baseline-final-for-windows-10-v1903-and-windows-server-v1903>.

       That publication drops periodic password expiration from their policy.

              •  Dropping the password-expiration policies that require
                 periodic password changes.  This change is discussed in
                 further detail below.

See also:


Revisions:

v2
  • Only remove some features of chage(1), but not the entire program.
  • Keep support for sp_lstchg == 0.
  • Keep passwd(1) -e.
v3
  • Rebase
$ git rd 
 1:  14542fe0f5d6 <  -:  ------------ *: expiry(1): Remove program
 2:  f3d202ba5089 =  1:  89661cf90859 *: chage(1): Remove interactive -I
 3:  f459a1858c94 =  2:  2c5fc86a212d *: chage(1): Remove interactive -m
 4:  548c28732d0b =  3:  92fb1b114bb9 *: chage(1): Remove interactive -M
 5:  59d18211b6a7 =  4:  0aa493de8d49 *: chage(1): Remove interactive -W
 6:  d8bb1d855ed2 =  5:  9648e1980136 *: chage(1): -I,--inactive: Remove option
 7:  368541756e3a =  6:  eef823f58f60 *: chage(1): -m,--mindays: Remove option
 8:  8a9f2928a38f =  7:  fb4b761a1d31 *: chage(1): -M,--maxdays: Remove option
 9:  ebcb2613391a =  8:  cfcc9591febd *: chage(1): -W,--warndays: Remove option
10:  4381c26fe9a2 !  9:  17e58f508ab3 *: passwd(1): -k,--keep-tokens: Remove option
    @@ lib/pam_pass.c
      {
        pam_handle_t *pamh = NULL;
        int flags = 0, ret;
    -@@ lib/pam_pass.c: void do_pam_passwd (const char *user, bool silent, bool change_expired)
      
        if (silent)
                flags |= PAM_SILENT;
    @@ src/passwd.c: main(int argc, char **argv)
     -  }
      
        if (anyflag && !amroot) {
    -           (void) fprintf (stderr, _("%s: Permission denied.\n"), Prog);
    + #ifdef WITH_AUDIT
     @@ src/passwd.c: main(int argc, char **argv)
                        do_pam_passwd_non_interactive ("passwd", name, cp);
                        erase_pass (cp);
11:  783f5718d100 = 10:  b3ea94811495 *: passwd(1): -n,--mindays: Remove option
12:  b64cbac2a338 = 11:  6bcaafcfde6f *: passwd(1): -x,--maxdays: Remove option
13:  b18a6b031720 = 12:  8125b5abf276 *: passwd(1): -i,--inactive: Remove option
14:  c9c2ad3c8e26 = 13:  4805c1fc272b *: passwd(1): -w,--warndays: Remove option
15:  87bbf32b556a = 14:  26ce7021578a *: useradd(8): -f,--inactive: Remove option
16:  bd06c767412b ! 15:  3dc5087c6845 *: usermod(8): -f,--inactive: Remove option
    @@ src/usermod.c: process_flags(int argc, char **argv, struct option_flags *flags)
        }
      
     @@ src/usermod.c: process_flags(int argc, char **argv, struct option_flags *flags)
    +   if (streq(user_newname, user_name)) {
    +           lflg = false;
    +   }
    +-  if (user_newinactive == user_inactive) {
    +-          fflg = false;
    +-  }
    +   if (user_newexpire == user_expire) {
    +           eflg = false;
    +   }
    +@@ src/usermod.c: process_flags(int argc, char **argv, struct option_flags *flags)
    +   }
    + 
    +   if (!(Uflg || uflg || sflg || pflg || mflg || Lflg ||
    +-        lflg || Gflg || gflg || fflg || eflg || dflg || cflg
    ++        lflg || Gflg || gflg || eflg || dflg || cflg
    + #ifdef ENABLE_SUBIDS
    +         || vflg || Vflg || wflg || Wflg
    + #endif                            /* ENABLE_SUBIDS */
    +@@ src/usermod.c: process_flags(int argc, char **argv, struct option_flags *flags)
    +           exit (E_SUCCESS);
        }
    - #endif                            /* WITH_SELINUX */
      
     -  if (!is_shadow_pwd && (eflg || fflg)) {
     +  if (!is_shadow_pwd && eflg) {
17:  298cd36264b1 ! 16:  ede0b49db209 *: login.defs(5): PASS_MIN_DAYS: Remove configuration variable
    @@ man/login.defs.5.xml
            HOME_MODE
     -      PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE
     +      PASS_MAX_DAYS PASS_WARN_AGE
    -       <phrase condition="sha_crypt">SHA_CRYPT_MAX_ROUNDS
    -       SHA_CRYPT_MIN_ROUNDS</phrase>
    +       SHA_CRYPT_MAX_ROUNDS SHA_CRYPT_MIN_ROUNDS
            SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
    +       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
     @@
        <term>pwck</term>
        <listitem>
18:  e524c3f82cd8 ! 17:  ff4eddd6dd19 *: login.defs(5): PASS_MAX_DAYS: Remove configuration variable
    @@ man/login.defs.5.xml
            HOME_MODE
     -      PASS_MAX_DAYS PASS_WARN_AGE
     +      PASS_WARN_AGE
    -       <phrase condition="sha_crypt">SHA_CRYPT_MAX_ROUNDS
    -       SHA_CRYPT_MIN_ROUNDS</phrase>
    +       SHA_CRYPT_MAX_ROUNDS SHA_CRYPT_MIN_ROUNDS
            SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
    +       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
     @@
        <term>pwck</term>
        <listitem>
19:  2169d73b023d ! 18:  198e6328990b *: login.defs(5): PASS_WARN_AGE: Remove configuration variable
    @@ man/login.defs.5.xml
            MAX_MEMBERS_PER_GROUP MD5_CRYPT_ENAB
            HOME_MODE
     -      PASS_WARN_AGE
    -       <phrase condition="sha_crypt">SHA_CRYPT_MAX_ROUNDS
    -       SHA_CRYPT_MIN_ROUNDS</phrase>
    +       SHA_CRYPT_MAX_ROUNDS SHA_CRYPT_MIN_ROUNDS
            SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
    +       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
     @@
        <term>pwck</term>
        <listitem>
20:  27da3ea45343 ! 19:  49861daaaf47 *: /etc/default/useradd: INACTIVE: Remove configuration variable
    @@ doc/HOWTO
        ##
     
      ## src/useradd.c ##
    -@@ src/useradd.c: static const char *def_usrtemplate = USRSKELDIR;
    - static const char *def_create_mail_spool = "yes";
    +@@ src/useradd.c: static const char *def_create_mail_spool = "yes";
    + static const char *def_btrfs_subvolume_home = "no";
      static const char *def_log_init = "yes";
      
     -static long def_inactive = -1;
21:  2549caa6c394 = 20:  64723d009713 *: shadow(5): sp_min: Ignore field, and clear it
22:  6a2d2f3d7d15 = 21:  ff19bdd6315e *: shadow(5): sp_max: Ignore field, and clear it
23:  5140c36771b9 = 22:  25445a691a07 *: shadow(5): sp_inact: Ignore field, and clear it
24:  332a3f9c2e64 = 23:  6fb3b6361bed *: shadow(5): sp_warn: Ignore field, and clear it
25:  cabb33c3cafb ! 24:  c299ba64a4f3 *: shadow(5): sp_lstchg: Reduce the allowed values to "0", and ""
    @@ lib/gettime.c (deleted)
     -gettime(void)
     -{
     -  char    *source_date_epoch;
    --  FILE    *shadow_logfd = log_get_logfd();
     -  time_t  fallback, epoch;
     -
     -  fallback = time (NULL);
    @@ lib/gettime.c (deleted)
     -          return fallback;
     -
     -  if (a2i(time_t, &epoch, source_date_epoch, NULL, 10, 0, fallback) == -1) {
    --          fprintf(shadow_logfd,
    +-          fprintf(log_get_logfd(),
     -                  _("Environment variable $SOURCE_DATE_EPOCH: a2i(\"%s\"): %s"),
     -                  source_date_epoch, strerrno());
     -          return fallback;
    @@ src/useradd.c: static void new_spent (struct spwd *spent)
     
      ## src/usermod.c ##
     @@ src/usermod.c: static void new_spent (struct spwd *spent, bool process_selinux)
    -   spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp);
    +   spent->sp_pwdp = new_pw_passwd(spent->sp_pwdp, process_selinux);
      
        if (pflg) {
     -          spent->sp_lstchg = gettime () / DAY;
26:  a991ac0edebd = 25:  ee6d4f550316 tests/system/tests/test_newusers.py: Remove tests where PAM differs from us.

v4: #1432 (comment)

v4b
  • Rebase
$ git rd 
 1:  b7463d3e =  1:  7852e171 *: chage(1): Remove interactive -I
 2:  2292584b =  2:  8e2121ce *: chage(1): Remove interactive -m
 3:  dd6a3393 =  3:  fc6c02af *: chage(1): Remove interactive -M
 4:  3720d04d =  4:  e7acbd25 *: chage(1): Remove interactive -W
 5:  e146115e =  5:  42e805f6 *: chage(1): -I,--inactive: Remove option
 6:  e8f925bd =  6:  ca84f2a9 *: chage(1): -m,--mindays: Remove option
 7:  81ce1fab =  7:  8c4827a3 *: chage(1): -M,--maxdays: Remove option
 8:  4bc186e4 =  8:  1d1ee796 *: chage(1): -W,--warndays: Remove option
 9:  c5a395b3 =  9:  94c837b9 *: passwd(1): -k,--keep-tokens: Remove option
10:  08766d1d = 10:  f0f918d1 *: passwd(1): -n,--mindays: Remove option
11:  3dd84922 = 11:  e064c050 *: passwd(1): -x,--maxdays: Remove option
12:  da66f2e0 = 12:  0b5ab1a3 *: passwd(1): -i,--inactive: Remove option
13:  081baf83 = 13:  9a6898ff *: passwd(1): -w,--warndays: Remove option
14:  f8464033 = 14:  3a5119ed *: useradd(8): -f,--inactive: Remove option
15:  d1038bb9 = 15:  349dfaeb *: usermod(8): -f,--inactive: Remove option
16:  77b7b733 = 16:  827fd65d *: login.defs(5): PASS_MIN_DAYS: Remove configuration variable
17:  55a6351e = 17:  426ca799 *: login.defs(5): PASS_MAX_DAYS: Remove configuration variable
18:  e681e738 = 18:  1a9b7798 *: login.defs(5): PASS_WARN_AGE: Remove configuration variable
19:  edf64429 = 19:  27de73fd *: /etc/default/useradd: INACTIVE: Remove configuration variable
20:  14196351 = 20:  347b4427 *: shadow(5): sp_min: Ignore field, and clear it
21:  b7f6451f = 21:  163a079d *: shadow(5): sp_max: Ignore field, and clear it
22:  9d7c5170 = 22:  6a5a9f4a *: shadow(5): sp_inact: Ignore field, and clear it
23:  f976cc3c = 23:  37a5a20b *: shadow(5): sp_warn: Ignore field, and clear it
24:  2e8e9287 = 24:  84bfa3c0 *: shadow(5): sp_lstchg: Reduce the allowed values to "0", and ""
25:  beb7769b = 25:  97a7f04a tests/system/tests/test_newusers.py: Remove tests where PAM differs from us.
v4c
  • Rebase
$ git rd 
 1:  7852e171 =  1:  9955beb8 *: chage(1): Remove interactive -I
 2:  8e2121ce =  2:  525efdf2 *: chage(1): Remove interactive -m
 3:  fc6c02af =  3:  abeac062 *: chage(1): Remove interactive -M
 4:  e7acbd25 =  4:  13f8cc65 *: chage(1): Remove interactive -W
 5:  42e805f6 =  5:  adedfdd9 *: chage(1): -I,--inactive: Remove option
 6:  ca84f2a9 =  6:  40b6a5ac *: chage(1): -m,--mindays: Remove option
 7:  8c4827a3 =  7:  2c40228f *: chage(1): -M,--maxdays: Remove option
 8:  1d1ee796 =  8:  f43961d1 *: chage(1): -W,--warndays: Remove option
 9:  94c837b9 =  9:  76ce79a5 *: passwd(1): -k,--keep-tokens: Remove option
10:  f0f918d1 = 10:  30c227f9 *: passwd(1): -n,--mindays: Remove option
11:  e064c050 = 11:  99f6413a *: passwd(1): -x,--maxdays: Remove option
12:  0b5ab1a3 = 12:  b1360c0a *: passwd(1): -i,--inactive: Remove option
13:  9a6898ff = 13:  077a2f21 *: passwd(1): -w,--warndays: Remove option
14:  3a5119ed = 14:  15efbf02 *: useradd(8): -f,--inactive: Remove option
15:  349dfaeb ! 15:  2be8b99e *: usermod(8): -f,--inactive: Remove option
    @@ man/usermod.8.xml
      ## src/usermod.c ##
     @@ src/usermod.c: static const char *user_selinux_range = NULL;
      static char *user_newshell;
    - static long user_expire;
    - static long user_newexpire;
    --static long user_inactive;
    --static long user_newinactive;
    - static long sys_ngroups;
    + static long user_expire = MISSING_TIME;
    + static long user_newexpire = MISSING_TIME;
    +-static long user_inactive = MISSING_TIME;
    +-static long user_newinactive = MISSING_TIME;
    + static size_t sys_ngroups;
      static char **user_groups;        /* NULL-terminated list */
      
     @@ src/usermod.c: static bool
16:  827fd65d ! 16:  aa56d446 *: login.defs(5): PASS_MIN_DAYS: Remove configuration variable
    @@ man/login.defs.5.xml
            &PASS_MAX_DAYS;
     -      &PASS_MIN_DAYS;
            &PASS_WARN_AGE;
    -       <para> 
    +       <para>
     -        <option>PASS_MAX_DAYS</option>, <option>PASS_MIN_DAYS</option> and
     +        <option>PASS_MAX_DAYS</option>, and
              <option>PASS_WARN_AGE</option> are only used at the
    @@ man/login.defs.5.xml
     -      PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE
     +      PASS_MAX_DAYS PASS_WARN_AGE
            SHA_CRYPT_MAX_ROUNDS SHA_CRYPT_MIN_ROUNDS
    -       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
    -       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
    +       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN SUB_GID_DETERMINISTIC
    +       SUB_GID_STORE_BY_UID
     @@
        <term>pwck</term>
        <listitem>
    @@ man/login.defs.5.xml
            MAIL_DIR MAX_MEMBERS_PER_GROUP
     -      PASS_MAX_DAYS PASS_MIN_DAYS PASS_WARN_AGE
     +      PASS_MAX_DAYS PASS_WARN_AGE
    -       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
    -       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
    -       SYS_GID_MAX SYS_GID_MIN SYS_UID_MAX SYS_UID_MIN UID_MAX UID_MIN
    +       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN SUB_GID_DETERMINISTIC
    +       SUB_GID_STORE_BY_UID
    +       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN SUB_UID_DETERMINISTIC
     
      ## man/login.defs.d/PASS_MIN_DAYS.xml (deleted) ##
     @@
    @@ tests/grouptools/groupdel/11_groupdel_invalid_option/config/etc/login.defs: KILL
      
      #
     
    - ## tests/grouptools/groupmems/54_groupmems_usage_invalid_option/config/etc/login.defs ##
    -@@ tests/grouptools/groupmems/54_groupmems_usage_invalid_option/config/etc/login.defs: KILLCHAR    025
    - # Password aging controls:
    - #
    - # PASS_MAX_DAYS   Maximum number of days a password may be used.
    --# PASS_MIN_DAYS   Minimum number of days allowed between password changes.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    - PASS_MAX_DAYS     99999
    --PASS_MIN_DAYS     0
    - PASS_WARN_AGE     7
    - 
    - #
    -
    - ## tests/grouptools/groupmems/55_groupmems_usage-a-d/config/etc/login.defs ##
    -@@ tests/grouptools/groupmems/55_groupmems_usage-a-d/config/etc/login.defs: KILLCHAR       025
    - # Password aging controls:
    - #
    - # PASS_MAX_DAYS   Maximum number of days a password may be used.
    --# PASS_MIN_DAYS   Minimum number of days allowed between password changes.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    - PASS_MAX_DAYS     99999
    --PASS_MIN_DAYS     0
    - PASS_WARN_AGE     7
    - 
    - #
    -
    - ## tests/grouptools/groupmems/56_groupmems_usage_extra_arg/config/etc/login.defs ##
    -@@ tests/grouptools/groupmems/56_groupmems_usage_extra_arg/config/etc/login.defs: KILLCHAR 025
    - # Password aging controls:
    - #
    - # PASS_MAX_DAYS   Maximum number of days a password may be used.
    --# PASS_MIN_DAYS   Minimum number of days allowed between password changes.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    - PASS_MAX_DAYS     99999
    --PASS_MIN_DAYS     0
    - PASS_WARN_AGE     7
    - 
    - #
    -
      ## tests/grouptools/groupmod/01_groupmod_change_gid/config/etc/login.defs ##
     @@ tests/grouptools/groupmod/01_groupmod_change_gid/config/etc/login.defs: KILLCHAR        025
      # Password aging controls:
17:  426ca799 ! 17:  73baa392 *: login.defs(5): PASS_MAX_DAYS: Remove configuration variable
    @@ man/login.defs.5.xml
            &PASS_CHANGE_TRIES;
     -      &PASS_MAX_DAYS;
            &PASS_WARN_AGE;
    -       <para> 
    +       <para>
     -        <option>PASS_MAX_DAYS</option>, and
     -        <option>PASS_WARN_AGE</option> are only used at the
     +        <option>PASS_WARN_AGE</option> is only used at the
    @@ man/login.defs.5.xml
     -      PASS_MAX_DAYS PASS_WARN_AGE
     +      PASS_WARN_AGE
            SHA_CRYPT_MAX_ROUNDS SHA_CRYPT_MIN_ROUNDS
    -       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
    -       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
    +       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN SUB_GID_DETERMINISTIC
    +       SUB_GID_STORE_BY_UID
     @@
        <term>pwck</term>
        <listitem>
    @@ man/login.defs.5.xml
            MAIL_DIR MAX_MEMBERS_PER_GROUP
     -      PASS_MAX_DAYS PASS_WARN_AGE
     +      PASS_WARN_AGE
    -       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
    -       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
    -       SYS_GID_MAX SYS_GID_MIN SYS_UID_MAX SYS_UID_MIN UID_MAX UID_MIN
    +       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN SUB_GID_DETERMINISTIC
    +       SUB_GID_STORE_BY_UID
    +       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN SUB_UID_DETERMINISTIC
     
      ## man/login.defs.d/PASS_MAX_DAYS.xml (deleted) ##
     @@
    @@ tests/grouptools/groupdel/11_groupdel_invalid_option/config/etc/login.defs: KILL
      
      #
     
    - ## tests/grouptools/groupmems/54_groupmems_usage_invalid_option/config/etc/login.defs ##
    -@@ tests/grouptools/groupmems/54_groupmems_usage_invalid_option/config/etc/login.defs: KILLCHAR    025
    - #
    - # Password aging controls:
    - #
    --# PASS_MAX_DAYS   Maximum number of days a password may be used.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    --PASS_MAX_DAYS     99999
    - PASS_WARN_AGE     7
    - 
    - #
    -
    - ## tests/grouptools/groupmems/55_groupmems_usage-a-d/config/etc/login.defs ##
    -@@ tests/grouptools/groupmems/55_groupmems_usage-a-d/config/etc/login.defs: KILLCHAR       025
    - #
    - # Password aging controls:
    - #
    --# PASS_MAX_DAYS   Maximum number of days a password may be used.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    --PASS_MAX_DAYS     99999
    - PASS_WARN_AGE     7
    - 
    - #
    -
    - ## tests/grouptools/groupmems/56_groupmems_usage_extra_arg/config/etc/login.defs ##
    -@@ tests/grouptools/groupmems/56_groupmems_usage_extra_arg/config/etc/login.defs: KILLCHAR 025
    - #
    - # Password aging controls:
    - #
    --# PASS_MAX_DAYS   Maximum number of days a password may be used.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    --PASS_MAX_DAYS     99999
    - PASS_WARN_AGE     7
    - 
    - #
    -
      ## tests/grouptools/groupmod/01_groupmod_change_gid/config/etc/login.defs ##
     @@ tests/grouptools/groupmod/01_groupmod_change_gid/config/etc/login.defs: KILLCHAR        025
      #
18:  1a9b7798 ! 18:  7cb6eb8c *: login.defs(5): PASS_WARN_AGE: Remove configuration variable
    @@ man/login.defs.5.xml
            &PASS_ALWAYS_WARN;
            &PASS_CHANGE_TRIES;
     -      &PASS_WARN_AGE;
    --      <para> 
    +-      <para>
     -        <option>PASS_WARN_AGE</option> is only used at the
     -        time of account creation. Any changes to these settings won't affect
     -        existing accounts.
    @@ man/login.defs.5.xml
            HOME_MODE
     -      PASS_WARN_AGE
            SHA_CRYPT_MAX_ROUNDS SHA_CRYPT_MIN_ROUNDS
    -       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
    -       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
    +       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN SUB_GID_DETERMINISTIC
    +       SUB_GID_STORE_BY_UID
     @@
        <term>pwck</term>
        <listitem>
    @@ man/login.defs.5.xml
            LASTLOG_UID_MAX
            MAIL_DIR MAX_MEMBERS_PER_GROUP
     -      PASS_WARN_AGE
    -       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN
    -       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN
    -       SYS_GID_MAX SYS_GID_MIN SYS_UID_MAX SYS_UID_MIN UID_MAX UID_MIN
    +       SUB_GID_COUNT SUB_GID_MAX SUB_GID_MIN SUB_GID_DETERMINISTIC
    +       SUB_GID_STORE_BY_UID
    +       SUB_UID_COUNT SUB_UID_MAX SUB_UID_MIN SUB_UID_DETERMINISTIC
     
      ## man/login.defs.d/PASS_WARN_AGE.xml (deleted) ##
     @@
    @@ tests/grouptools/groupdel/11_groupdel_invalid_option/config/etc/login.defs: KILL
      # mind.
      #UMASK            022
      
    --#
    --# Password aging controls:
    --#
    --# PASS_WARN_AGE   Number of days warning given before a password expires.
    --#
    --PASS_WARN_AGE     7
    --
    - #
    - # Min/max values for automatic uid selection in useradd
    - #
    -
    - ## tests/grouptools/groupmems/54_groupmems_usage_invalid_option/config/etc/login.defs ##
    -@@ tests/grouptools/groupmems/54_groupmems_usage_invalid_option/config/etc/login.defs: KILLCHAR    025
    - # mind.
    - #UMASK            022
    - 
    --#
    --# Password aging controls:
    --#
    --# PASS_WARN_AGE   Number of days warning given before a password expires.
    --#
    --PASS_WARN_AGE     7
    --
    - #
    - # Min/max values for automatic uid selection in useradd
    - #
    -
    - ## tests/grouptools/groupmems/55_groupmems_usage-a-d/config/etc/login.defs ##
    -@@ tests/grouptools/groupmems/55_groupmems_usage-a-d/config/etc/login.defs: KILLCHAR       025
    - # mind.
    - #UMASK            022
    - 
    --#
    --# Password aging controls:
    --#
    --# PASS_WARN_AGE   Number of days warning given before a password expires.
    --#
    --PASS_WARN_AGE     7
    --
    - #
    - # Min/max values for automatic uid selection in useradd
    - #
    -
    - ## tests/grouptools/groupmems/56_groupmems_usage_extra_arg/config/etc/login.defs ##
    -@@ tests/grouptools/groupmems/56_groupmems_usage_extra_arg/config/etc/login.defs: KILLCHAR 025
    - # mind.
    - #UMASK            022
    - 
     -#
     -# Password aging controls:
     -#
19:  27de73fd = 19:  27c12ffe *: /etc/default/useradd: INACTIVE: Remove configuration variable
20:  347b4427 = 20:  c111901c *: shadow(5): sp_min: Ignore field, and clear it
21:  163a079d = 21:  3445b525 *: shadow(5): sp_max: Ignore field, and clear it
22:  6a5a9f4a = 22:  ec5e5722 *: shadow(5): sp_inact: Ignore field, and clear it
23:  37a5a20b = 23:  5b8d01ba *: shadow(5): sp_warn: Ignore field, and clear it
24:  84bfa3c0 = 24:  ee6d0b22 *: shadow(5): sp_lstchg: Reduce the allowed values to "0", and ""
25:  97a7f04a = 25:  ad3cc6af tests/system/tests/test_newusers.py: Remove tests where PAM differs from us.
v5
$ git range-diff master..gh/expiry sp_min..expiry 
 1:  9955beb8 =  1:  f04e25f1 *: chage(1): Remove interactive -I
 2:  525efdf2 <  -:  -------- *: chage(1): Remove interactive -m
 3:  abeac062 !  2:  620623ab *: chage(1): Remove interactive -M
    @@ Commit message
     
      ## src/chage.c ##
     @@ src/chage.c: static int new_fields (void)
    +   (void) puts (_("Enter the new value, or press ENTER for the default"));
        (void) puts ("");
      
    -   mindays = -1;
    --
     -  stprintf_a(buf, "%ld", maxdays);
     -  change_field(buf, sizeof(buf), _("Maximum Password Age"));
     -  if (a2sl(&maxdays, buf, NULL, 0, -1, LONG_MAX) == -1)
 4:  13f8cc65 =  3:  2b0a7a8d *: chage(1): Remove interactive -W
 5:  adedfdd9 !  4:  ad85ab5e *: chage(1): -I,--inactive: Remove option
    @@ src/chage.c: static bool
          iflg = false,         /* set iso8601 date formatting */
     -    Iflg = false,         /* set password inactive after expiration */
          lflg = false,         /* show account aging information */
    -     mflg = false,         /* set minimum number of days before password change */
          Mflg = false,         /* set maximum number of days before password change */
    +     Wflg = false;         /* set expiration warning days */
     @@ src/chage.c: usage (int status)
        (void) fputs (_("  -E, --expiredate EXPIRE_DATE  set account expiration date to EXPIRE_DATE\n"), usageout);
        (void) fputs (_("  -h, --help                    display this help message and exit\n"), usageout);
    @@ src/chage.c: usage (int status)
     -  (void) fputs (_("  -I, --inactive INACTIVE       set password inactive after expiration\n"
     -                  "                                to INACTIVE\n"), usageout);
        (void) fputs (_("  -l, --list                    show account aging information\n"), usageout);
    -   (void) fputs (_("  -m, --mindays MIN_DAYS        set minimum number of days before password\n"
    -                   "                                change to MIN_DAYS\n"), usageout);
    +   (void) fputs (_("  -M, --maxdays MAX_DAYS        set maximum number of days before password\n"
    +                   "                                change to MAX_DAYS\n"), usageout);
     @@ src/chage.c: static void process_flags (int argc, char **argv, struct option_flags *flags)
                {"lastday",    required_argument, NULL, 'd'},
                {"expiredate", required_argument, NULL, 'E'},
                {"help",       no_argument,       NULL, 'h'},
     -          {"inactive",   required_argument, NULL, 'I'},
                {"list",       no_argument,       NULL, 'l'},
    -           {"mindays",    required_argument, NULL, 'm'},
                {"maxdays",    required_argument, NULL, 'M'},
    +           {"root",       required_argument, NULL, 'R'},
     @@ src/chage.c: static void process_flags (int argc, char **argv, struct option_flags *flags)
                case 'i':
                        iflg = true;
    @@ src/chage.c: static void check_flags (int argc, int opt_index)
                usage (E_USAGE);
        }
      
    --  if (lflg && (mflg || Mflg || dflg || Wflg || Iflg || Eflg)) {
    -+  if (lflg && (mflg || Mflg || dflg || Wflg || Eflg)) {
    +-  if (lflg && (Mflg || dflg || Wflg || Iflg || Eflg)) {
    ++  if (lflg && (Mflg || dflg || Wflg || Eflg)) {
                fprintf (stderr,
                         _("%s: do not include \"l\" with other flags\n"),
                         Prog);
    @@ src/chage.c: static void get_defaults (/*@null@*/const struct spwd *sp)
     - *        -I      set password inactive after expiration (*)
       *        -l      show account aging information
       *        -M      set maximum number of days before password change (*)
    -  *        -m      set minimum number of days before password change (*)
    +  *        -W      set expiration warning days (*)
     @@ src/chage.c: int main (int argc, char **argv)
         * If none of the fields were changed from the command line, let the
         * user interactively change them.
         */
    --  if (!mflg && !Mflg && !dflg && !Wflg && !Iflg && !Eflg) {
    -+  if (!mflg && !Mflg && !dflg && !Wflg && !Eflg) {
    +-  if (!Mflg && !dflg && !Wflg && !Iflg && !Eflg) {
    ++  if (!Mflg && !dflg && !Wflg && !Eflg) {
                printf (_("Changing the aging information for %s\n"),
                        user_name);
                if (new_fields () == 0) {
    @@ tests/chage/03_chsh_usage/data/usage.out: Options:
     -  -I, --inactive INACTIVE       set password inactive after expiration
     -                                to INACTIVE
        -l, --list                    show account aging information
    -   -m, --mindays MIN_DAYS        set minimum number of days before password
    -                                 change to MIN_DAYS
    +   -M, --maxdays MAX_DAYS        set maximum number of days before password
    +                                 change to MAX_DAYS
     
      ## tests/chage/04_chsh_usage_invalid_option/data/usage.out ##
     @@ tests/chage/04_chsh_usage_invalid_option/data/usage.out: Options:
    @@ tests/chage/04_chsh_usage_invalid_option/data/usage.out: Options:
     -  -I, --inactive INACTIVE       set password inactive after expiration
     -                                to INACTIVE
        -l, --list                    show account aging information
    -   -m, --mindays MIN_DAYS        set minimum number of days before password
    -                                 change to MIN_DAYS
    +   -M, --maxdays MAX_DAYS        set maximum number of days before password
    +                                 change to MAX_DAYS
     
      ## tests/chage/05_chsh_usage_2_users/chage.test (deleted) ##
     @@
    @@ tests/chage/07_chsh_usage-l_exclusive/data/usage.out: Options:
     -  -I, --inactive INACTIVE       set password inactive after expiration
     -                                to INACTIVE
        -l, --list                    show account aging information
    -   -m, --mindays MIN_DAYS        set minimum number of days before password
    -                                 change to MIN_DAYS
    +   -M, --maxdays MAX_DAYS        set maximum number of days before password
    +                                 change to MAX_DAYS
     
      ## tests/chage/08_chsh_usage_invalid_date/data/usage.out ##
     @@ tests/chage/08_chsh_usage_invalid_date/data/usage.out: Options:
    @@ tests/chage/08_chsh_usage_invalid_date/data/usage.out: Options:
     -  -I, --inactive INACTIVE       set password inactive after expiration
     -                                to INACTIVE
        -l, --list                    show account aging information
    -   -m, --mindays MIN_DAYS        set minimum number of days before password
    -                                 change to MIN_DAYS
    +   -M, --maxdays MAX_DAYS        set maximum number of days before password
    +                                 change to MAX_DAYS
     
      ## tests/chage/09_chsh_usage_invalid_numeric_arg/data/usage.out ##
     @@ tests/chage/09_chsh_usage_invalid_numeric_arg/data/usage.out: Options:
    @@ tests/chage/09_chsh_usage_invalid_numeric_arg/data/usage.out: Options:
     -  -I, --inactive INACTIVE       set password inactive after expiration
     -                                to INACTIVE
        -l, --list                    show account aging information
    -   -m, --mindays MIN_DAYS        set minimum number of days before password
    -                                 change to MIN_DAYS
    +   -M, --maxdays MAX_DAYS        set maximum number of days before password
    +                                 change to MAX_DAYS
     
      ## tests/chage/11_chsh_usage_invalid_user/chage.test (deleted) ##
     @@
    @@ tests/run_all: run_test ./su/10_su_sulog_success/su.test
     -run_test ./chage/13_chsh_locked_passwd/chage.test
     -run_test ./chage/14_chsh_locked_shadow/chage.test
     -run_test ./chage/15_chage-I_no_shadow_entry/chage.test
    - run_test ./chage/16_chage-m_no_shadow_entry/chage.test
      run_test ./chage/17_chage-M_no_shadow_entry/chage.test
      run_test ./chage/18_chage-d_no_shadow_entry/chage.test
      run_test ./chage/19_chage-W_no_shadow_entry/chage.test
    @@ tests/run_all.coverage: run_test ./su/10_su_sulog_success/su.test
     -run_test ./chage/13_chsh_locked_passwd/chage.test
     -run_test ./chage/14_chsh_locked_shadow/chage.test
     -run_test ./chage/15_chage-I_no_shadow_entry/chage.test
    - run_test ./chage/16_chage-m_no_shadow_entry/chage.test
      run_test ./chage/17_chage-M_no_shadow_entry/chage.test
      run_test ./chage/18_chage-d_no_shadow_entry/chage.test
      run_test ./chage/19_chage-W_no_shadow_entry/chage.test
 6:  40b6a5ac <  -:  -------- *: chage(1): -m,--mindays: Remove option
 7:  2c40228f !  5:  373aeeb7 *: chage(1): -M,--maxdays: Remove option
    @@ src/chage.c: static void get_defaults (/*@null@*/const struct spwd *sp)
     -                  maxdays = sp->sp_max;
     -          }
     +          maxdays = sp->sp_max;
    -           mindays = sp->sp_min;
                if (!dflg) {
                        lstchgdate = sp->sp_lstchg;
    +           }
     @@ src/chage.c: static void get_defaults (/*@null@*/const struct spwd *sp)
                 * Use default values that will not change the behavior of the
                 * account.
    @@ src/chage.c: static void get_defaults (/*@null@*/const struct spwd *sp)
     -                  maxdays = -1;
     -          }
     +          maxdays = -1;
    -           mindays = -1;
                if (!dflg) {
                        lstchgdate = -1;
    +           }
     @@ src/chage.c: static void get_defaults (/*@null@*/const struct spwd *sp)
       *        -d      set last password change date (*)
       *        -E      set account expiration date (*)
 8:  f43961d1 =  6:  ea5c847d *: chage(1): -W,--warndays: Remove option
 9:  76ce79a5 !  7:  3222e71e *: passwd(1): -k,--keep-tokens: Remove option
    @@ src/passwd.c: static bool
          iflg = false,                 /* -i - set inactive days */
     -    kflg = false,                 /* -k - change only if expired */
          lflg = false,                 /* -l - lock the user's password */
    -     nflg = false,                 /* -n - set minimum days */
          qflg = false,                 /* -q - quiet mode */
    +     Sflg = false,                 /* -S - show password status */
     @@ src/passwd.c: usage (int status)
        (void) fputs (_("  -d, --delete                  delete the password for the named account\n"), usageout);
        (void) fputs (_("  -e, --expire                  force expire the password for the named account\n"), usageout);
    @@ src/passwd.c: main(int argc, char **argv)
                        {"inactive",    required_argument, NULL, 'i'},
     -                  {"keep-tokens", no_argument,       NULL, 'k'},
                        {"lock",        no_argument,       NULL, 'l'},
    -                   {"mindays",     required_argument, NULL, 'n'},
                        {"quiet",       no_argument,       NULL, 'q'},
    +                   {"repository",  required_argument, NULL, 'r'},
     @@ src/passwd.c: main(int argc, char **argv)
                                iflg = true;
                                anyflag = true;
10:  30c227f9 <  -:  -------- *: passwd(1): -n,--mindays: Remove option
11:  99f6413a =  8:  282179ca *: passwd(1): -x,--maxdays: Remove option
12:  b1360c0a !  9:  fce25a8a *: passwd(1): -i,--inactive: Remove option
    @@ src/passwd.c: usage (int status)
     @@ src/passwd.c: static void check_password (const struct passwd *pw, const struct spwd *sp, bool
        /*
         * Expired accounts cannot be changed ever. Passwords which are
    -    * locked may not be changed. Passwords where min > max may not be
    --   * changed. Passwords which have been inactive too long cannot be
    -    * changed.
    +    * locked may not be changed.
    +-   * Passwords which have been inactive too long cannot be changed.
         */
        if (   strprefix(sp->sp_pwdp, "!")
    +       || (exp_status > 1)) {
     @@ src/passwd.c: static void update_shadow(bool process_selinux)
        if (wflg) {
                nsp->sp_warn = warn;
13:  077a2f21 = 10:  bcc65cea *: passwd(1): -w,--warndays: Remove option
14:  15efbf02 = 11:  42391faa *: useradd(8): -f,--inactive: Remove option
15:  2be8b99e = 12:  25220eec *: usermod(8): -f,--inactive: Remove option
16:  aa56d446 <  -:  -------- *: login.defs(5): PASS_MIN_DAYS: Remove configuration variable
17:  73baa392 = 13:  d5bfe75b *: login.defs(5): PASS_MAX_DAYS: Remove configuration variable
18:  7cb6eb8c = 14:  bc8f66b9 *: login.defs(5): PASS_WARN_AGE: Remove configuration variable
19:  27c12ffe = 15:  fbdcd79f *: /etc/default/useradd: INACTIVE: Remove configuration variable
20:  c111901c <  -:  -------- *: shadow(5): sp_min: Ignore field, and clear it
21:  3445b525 = 16:  f76eac62 *: shadow(5): sp_max: Ignore field, and clear it
22:  ec5e5722 = 17:  bdd51230 *: shadow(5): sp_inact: Ignore field, and clear it
23:  5b8d01ba = 18:  4b8b3ff6 *: shadow(5): sp_warn: Ignore field, and clear it
24:  ee6d0b22 = 19:  0a9be8ae *: shadow(5): sp_lstchg: Reduce the allowed values to "0", and ""
25:  ad3cc6af = 20:  1da5e8d1 tests/system/tests/test_newusers.py: Remove tests where PAM differs from us.

@alejandro-colomar alejandro-colomar force-pushed the expiry branch 5 times, most recently from ffbc9db to 9e20651 Compare December 16, 2025 02:00
@alejandro-colomar alejandro-colomar self-assigned this Dec 16, 2025
@alejandro-colomar alejandro-colomar force-pushed the expiry branch 20 times, most recently from 3b95665 to 36b8271 Compare December 16, 2025 21:24
Comment thread src/passwd.c Fixed
@alejandro-colomar
Copy link
Copy Markdown
Collaborator Author

v4

range-diff
  • Rebase
$ git rd -U0
 1:  89661cf9 !  1:  b7463d3e *: chage(1): Remove interactive -I
    @@ tests/chage/36_chage_interactive-I_invalid1/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
    @@ tests/chage/37_chage_interactive-I_invalid2/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
    @@ tests/chage/38_chage_interactive-I-1/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
 2:  2c5fc86a =  2:  2292584b *: chage(1): Remove interactive -m
 3:  92fb1b11 =  3:  dd6a3393 *: chage(1): Remove interactive -M
 4:  0aa493de !  4:  3720d04d *: chage(1): Remove interactive -W
    @@ tests/chage/33_chage_interactive-W_invalid1/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
    @@ tests/chage/34_chage_interactive-W_invalid2/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
    @@ tests/chage/35_chage_interactive-W-1/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
 5:  9648e198 !  5:  e146115e *: chage(1): -I,--inactive: Remove option
    @@ tests/chage/15_chage-I_no_shadow_entry/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
    @@ tests/failures/chage/01_chage_openRW_passwd_failure/config/etc/login.defs (delet
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
    @@ tests/failures/chage/03_chage_openRW_shadow_failure/config/etc/login.defs (delet
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
    @@ tests/failures/chage/05_chage_rename_shadow_failure/config/etc/login.defs (delet
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
    @@ tests/failures/chage/06_chage_rename_passwd_failure/config/etc/login.defs (delet
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
 6:  eef823f5 !  6:  e8f925bd *: chage(1): -m,--mindays: Remove option
    @@ tests/chage/16_chage-m_no_shadow_entry/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
 7:  fb4b761a !  7:  81ce1fab *: chage(1): -M,--maxdays: Remove option
    @@ tests/chage/17_chage-M_no_shadow_entry/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
 8:  cfcc9591 !  8:  4bc186e4 *: chage(1): -W,--warndays: Remove option
    @@ tests/chage/19_chage-W_no_shadow_entry/config/etc/login.defs (deleted)
    --#
    --# Only works if compiled with MD5_CRYPT defined:
    --# If set to "yes", new passwords will be encrypted using the MD5-based
    --# algorithm compatible with the one used by recent releases of FreeBSD.
    --# It supports passwords of unlimited length and longer salt strings.
    --# Set to "no" if you need to copy encrypted passwords to other systems
    --# which don't understand the new algorithm.  Default is "no".
    --#
    --# This variable is used by chpasswd, gpasswd and newusers.
    --#
    --#MD5_CRYPT_ENAB   no
    --
 9:  17e58f50 =  9:  c5a395b3 *: passwd(1): -k,--keep-tokens: Remove option
10:  b3ea9481 = 10:  08766d1d *: passwd(1): -n,--mindays: Remove option
11:  6bcaafcf = 11:  3dd84922 *: passwd(1): -x,--maxdays: Remove option
12:  8125b5ab = 12:  da66f2e0 *: passwd(1): -i,--inactive: Remove option
13:  4805c1fc = 13:  081baf83 *: passwd(1): -w,--warndays: Remove option
14:  26ce7021 = 14:  f8464033 *: useradd(8): -f,--inactive: Remove option
15:  3dc5087c ! 15:  d1038bb9 *: usermod(8): -f,--inactive: Remove option
    @@ src/usermod.c: static void new_spent (struct spwd *spent, bool process_selinux)
    --          SYSLOG ((LOG_INFO,
    --                   "change user '%s' inactive from '%ld' to '%ld'",
    --                   spent->sp_namp, spent->sp_inact, user_newinactive));
    +-          SYSLOG(LOG_INFO, "change user '%s' inactive from '%ld' to '%ld'",
    +-                 spent->sp_namp, spent->sp_inact, user_newinactive);
16:  ede0b49d ! 16:  77b7b733 *: login.defs(5): PASS_MIN_DAYS: Remove configuration variable
    @@ man/login.defs.5.xml
    -       MAX_MEMBERS_PER_GROUP MD5_CRYPT_ENAB
    +       MAX_MEMBERS_PER_GROUP
    @@ man/newusers.8.xml
    + <!ENTITY HOME_MODE             SYSTEM "login.defs.d/HOME_MODE.xml">
    @@ man/newusers.8.xml
    - <!ENTITY MD5_CRYPT_ENAB        SYSTEM "login.defs.d/MD5_CRYPT_ENAB.xml">
    @@ tests/chroot/usermod/01_usermod--root/config_chroot/etc/login.defs: UMASK                022
    - ## tests/crypt/login.defs_DES-MD5_CRYPT_ENAB/config/etc/login.defs ##
    -@@ tests/crypt/login.defs_DES-MD5_CRYPT_ENAB/config/etc/login.defs: KILLCHAR       025
    - # Password aging controls:
    - #
    - # PASS_MAX_DAYS   Maximum number of days a password may be used.
    --# PASS_MIN_DAYS   Minimum number of days allowed between password changes.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    - PASS_MAX_DAYS     99999
    --PASS_MIN_DAYS     0
    - PASS_WARN_AGE     7
    - 
    - #
    -
    @@ tests/crypt/login.defs_MD5/config/etc/login.defs: KILLCHAR       025
    - ## tests/crypt/login.defs_MD5_CRYPT_ENAB/config/etc/login.defs ##
    -@@ tests/crypt/login.defs_MD5_CRYPT_ENAB/config/etc/login.defs: KILLCHAR   025
    - # Password aging controls:
    - #
    - # PASS_MAX_DAYS   Maximum number of days a password may be used.
    --# PASS_MIN_DAYS   Minimum number of days allowed between password changes.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    - PASS_MAX_DAYS     99999
    --PASS_MIN_DAYS     0
    - PASS_WARN_AGE     7
    - 
    - #
    -
17:  ff4eddd6 ! 17:  55a6351e *: login.defs(5): PASS_MAX_DAYS: Remove configuration variable
    @@ man/login.defs.5.xml
    -       MAX_MEMBERS_PER_GROUP MD5_CRYPT_ENAB
    +       MAX_MEMBERS_PER_GROUP
    @@ man/newusers.8.xml
    + <!ENTITY GID_MAX               SYSTEM "login.defs.d/GID_MAX.xml">
    @@ man/newusers.8.xml
    - <!ENTITY MD5_CRYPT_ENAB        SYSTEM "login.defs.d/MD5_CRYPT_ENAB.xml">
    @@ man/newusers.8.xml
    -       &MD5_CRYPT_ENAB;
    +       &MAX_MEMBERS_PER_GROUP;
    @@ tests/chroot/usermod/01_usermod--root/config_chroot/etc/login.defs: UMASK                022
    - ## tests/crypt/login.defs_DES-MD5_CRYPT_ENAB/config/etc/login.defs ##
    -@@ tests/crypt/login.defs_DES-MD5_CRYPT_ENAB/config/etc/login.defs: KILLCHAR       025
    - #
    - # Password aging controls:
    - #
    --# PASS_MAX_DAYS   Maximum number of days a password may be used.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    --PASS_MAX_DAYS     99999
    - PASS_WARN_AGE     7
    - 
    - #
    -
    @@ tests/crypt/login.defs_MD5/config/etc/login.defs: KILLCHAR       025
    - ## tests/crypt/login.defs_MD5_CRYPT_ENAB/config/etc/login.defs ##
    -@@ tests/crypt/login.defs_MD5_CRYPT_ENAB/config/etc/login.defs: KILLCHAR   025
    - #
    - # Password aging controls:
    - #
    --# PASS_MAX_DAYS   Maximum number of days a password may be used.
    - # PASS_WARN_AGE   Number of days warning given before a password expires.
    - #
    --PASS_MAX_DAYS     99999
    - PASS_WARN_AGE     7
    - 
    - #
    -
18:  198e6328 ! 18:  e681e738 *: login.defs(5): PASS_WARN_AGE: Remove configuration variable
    @@ man/login.defs.5.xml
    -       MAX_MEMBERS_PER_GROUP MD5_CRYPT_ENAB
    +       MAX_MEMBERS_PER_GROUP
    @@ man/newusers.8.xml
    + <!ENTITY GID_MAX               SYSTEM "login.defs.d/GID_MAX.xml">
    @@ man/newusers.8.xml
    - <!ENTITY MD5_CRYPT_ENAB        SYSTEM "login.defs.d/MD5_CRYPT_ENAB.xml">
    @@ man/newusers.8.xml
    -     <variablelist condition="no_pam">
    -       &MD5_CRYPT_ENAB;
    +       &HOME_MODE;
    +       &MAX_MEMBERS_PER_GROUP;
    @@ tests/convtools/01/run: save()
    - ## tests/crypt/login.defs_DES-MD5_CRYPT_ENAB/config/etc/login.defs ##
    -@@ tests/crypt/login.defs_DES-MD5_CRYPT_ENAB/config/etc/login.defs: KILLCHAR       025
    - # mind.
    - #UMASK            022
    - 
    --#
    --# Password aging controls:
    --#
    --# PASS_WARN_AGE   Number of days warning given before a password expires.
    --#
    --PASS_WARN_AGE     7
    --
    - #
    - # Min/max values for automatic uid selection in useradd
    - #
    -
    @@ tests/crypt/login.defs_MD5/config/etc/login.defs: KILLCHAR       025
    - # mind.
    - #UMASK            022
    - 
    --#
    --# Password aging controls:
    --#
    --# PASS_WARN_AGE   Number of days warning given before a password expires.
    --#
    --PASS_WARN_AGE     7
    --
    - #
    - # Min/max values for automatic uid selection in useradd
    - #
    -
    - ## tests/crypt/login.defs_MD5_CRYPT_ENAB/config/etc/login.defs ##
    -@@ tests/crypt/login.defs_MD5_CRYPT_ENAB/config/etc/login.defs: KILLCHAR   025
19:  49861daa ! 19:  edf64429 *: /etc/default/useradd: INACTIVE: Remove configuration variable
    @@ src/useradd.c: set_defaults(void)
    -   SYSLOG ((LOG_INFO,
    +   SYSLOG(LOG_INFO,
    @@ src/useradd.c: set_defaults(void)
    -            def_create_mail_spool, def_log_init));
    +            def_create_mail_spool, def_log_init);
    @@ tests/grouptools/chgpasswd/07_chgpasswd_usage_bad_option/config/etc/default/user
    - ## tests/grouptools/chgpasswd/08_chgpasswd_usage-e-m_exclusive/config/etc/default/useradd ##
    -@@ tests/grouptools/chgpasswd/08_chgpasswd_usage-e-m_exclusive/config/etc/default/useradd: GROUP=10
    - # The default home directory. Same as DHOME for adduser
    - HOME=/tmp
    - #
    --# The number of days after a password expires until the account 
    --# is permanently disabled
    --INACTIVE=12
    --#
    - # The default expire date
    - EXPIRE=2007-12-02
    - #
    -
    @@ tests/grouptools/chgpasswd/09_chgpasswd_usage-e-c_exclusive/config/etc/default/u
    - ## tests/grouptools/chgpasswd/10_chgpasswd_usage-m-c_exclusive/config/etc/default/useradd ##
    -@@ tests/grouptools/chgpasswd/10_chgpasswd_usage-m-c_exclusive/config/etc/default/useradd: GROUP=10
    - # The default home directory. Same as DHOME for adduser
    - HOME=/tmp
    - #
    --# The number of days after a password expires until the account 
    --# is permanently disabled
    --INACTIVE=12
    --#
    - # The default expire date
    - EXPIRE=2007-12-02
    - #
    -
    @@ tests/usertools/chpasswd-PAM/07_chpasswd_usage_bad_option/config/etc/default/use
    - ## tests/usertools/chpasswd-PAM/08_chpasswd_usage-e-m_exclusive/config/etc/default/useradd ##
    -@@ tests/usertools/chpasswd-PAM/08_chpasswd_usage-e-m_exclusive/config/etc/default/useradd: GROUP=10
    - # The default home directory. Same as DHOME for adduser
    - HOME=/tmp
    - #
    --# The number of days after a password expires until the account 
    --# is permanently disabled
    --INACTIVE=12
    --#
    - # The default expire date
    - EXPIRE=2007-12-02
    - #
    -
    @@ tests/usertools/chpasswd-PAM/09_chpasswd_usage-e-c_exclusive/config/etc/default/
    - ## tests/usertools/chpasswd-PAM/10_chpasswd_usage-m-c_exclusive/config/etc/default/useradd ##
    -@@ tests/usertools/chpasswd-PAM/10_chpasswd_usage-m-c_exclusive/config/etc/default/useradd: GROUP=10
    - # The default home directory. Same as DHOME for adduser
    - HOME=/tmp
    - #
    --# The number of days after a password expires until the account 
    --# is permanently disabled
    --INACTIVE=12
    --#
    - # The default expire date
    - EXPIRE=2007-12-02
    - #
    -
20:  64723d00 ! 20:  14196351 *: shadow(5): sp_min: Ignore field, and clear it
    @@ src/passwd.c: static void check_password (const struct passwd *pw, const struct
    --                  SYSLOG ((LOG_WARN, "now < minimum age for '%s'", sp->sp_namp));
    +-                  SYSLOG(LOG_WARN, "now < minimum age for '%s'", sp->sp_namp);
21:  ff19bdd6 = 21:  b7f6451f *: shadow(5): sp_max: Ignore field, and clear it
22:  25445a69 = 22:  9d7c5170 *: shadow(5): sp_inact: Ignore field, and clear it
23:  6fb3b636 = 23:  f976cc3c *: shadow(5): sp_warn: Ignore field, and clear it
24:  c299ba64 = 24:  2e8e9287 *: shadow(5): sp_lstchg: Reduce the allowed values to "0", and ""
25:  ee6d4f55 = 25:  beb7769b tests/system/tests/test_newusers.py: Remove tests where PAM differs from us.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
It makes no sense to limit the frequency of password change.  If one
changes its password, and 5 minutes later the password is leaked, one
should be able to change the password immediately.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Whenever we were reading it, let's assume it contains a -1 (the integer
representation of an empty field).  Whenever we were writing it, let's
write a -1.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Which are mapped to 0 and -1.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
…rom us.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants