Description of problem: If "maxlife" of password policy is undefined, password expiration is set to current day + 90. This value is undocumented. The behaviour should be align with (https://bugzilla.redhat.com/show_bug.cgi?id=826790) to disable password expiration. Alternatively, update product documentation to specify this default value (90). ======================== $ ipa pwpolicy-find Group: ipausers Priority: 10 Grace login limit: -1 Group: global_policy Max lifetime (days): 90 Min lifetime (hours): 1 History size: 0 Character classes: 0 Min length: 8 Max failures: 6 Failure reset interval: 60 Lockout duration: 600 Grace login limit: -1 ---------------------------- Number of entries returned 2 ---------------------------- $ ipa pwpolicy-show --user=user1 Group: ipausers Grace login limit: -1 $ ipa user-show user1 --all dn: uid=user1,cn=users,cn=accounts,dc=<...> User login: user1 First name: Userfirst Last name: Userlast Full name: Userfirst Userlast Display name: Userfirst Userlast Initials: UU Home directory: /home/user1 GECOS: Userfirst Userlast Login shell: /bin/sh Principal name: user1@<...> Principal alias: user1@<...> User password expiration: 20230802062556Z <<<<<===== Email address: user1@<...> UID: 1188200003 GID: 1188200003 Account disabled: False Preserved user: False Password: True Member of groups: ipausers Kerberos keys available: True ipantsecurityidentifier: S-1-5-21-<...> ipauniqueid: a4c2c5ce-<...> krbextradata: AAL0T1Nka2FkbWluZEBTVVdVUkhFTDlBLkxBQi5QU0kuUE5RMi5SRURIQVQuQ09NAA== krblastpwdchange: 20230504062556Z krbloginfailedcount: 0 krbpwdpolicyreference: cn=ipausers,cn=<...> krbticketflags: 128 mepmanagedentry: cn=user1,cn=groups,cn=accounts,dc=<...> objectclass: top, person, organizationalperson, inetorgperson, inetuser, posixaccount, krbprincipalaux, krbticketpolicyaux, ipaobject, ipasshuser, ipaSshGroupOfPubKeys, mepOriginEntry, ipantuserattrs $ ipa user-mod user1 --password-expiration=20500101010000Z --------------------- Modified user "user1" --------------------- User login: user1 First name: Userfirst Last name: Userlast Home directory: /home/user1 Login shell: /bin/sh Principal name: user1@<...> Principal alias: user1@<...> User password expiration: 20500101010000Z Email address: user1@<...> UID: 1188200003 GID: 1188200003 Account disabled: False Password: True Member of groups: ipausers Kerberos keys available: True ========== $ id uid=1188200003(user1) gid=1188200003(user1) groups=1188200003(user1) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 $ passwd Changing password for user user1. Current Password: New password: Retype new password: passwd: all authentication tokens updated successfully. $ ipa user-show user1 --all dn: uid=user1,cn=users,cn=accounts,dc=<...> User login: user1 First name: Userfirst Last name: Userlast Full name: Userfirst Userlast Display name: Userfirst Userlast Initials: UU Home directory: /home/user1 GECOS: Userfirst Userlast Login shell: /bin/sh Principal name: user1@<...> Principal alias: user1@<...> User password expiration: 20230802063701Z <<<<<===== Email address: user1@<...> UID: 1188200003 GID: 1188200003 Account disabled: False Preserved user: False Password: True Member of groups: ipausers Kerberos keys available: True ipantsecurityidentifier: S-1-5-21-<...> ipauniqueid: a4c2c5ce-<...> krblastpwdchange: 20230504063701Z objectclass: top, person, organizationalperson, inetorgperson, inetuser, posixaccount, krbprincipalaux, krbticketpolicyaux, ipaobject, ipasshuser, ipaSshGroupOfPubKeys, mepOriginEntry, ipantuserattrs password expiration is disabled if maxlife=0 ============================================================= $ ipa pwpolicy-mod ipausers --maxlife=0 --minlife=0 Group: ipausers Max lifetime (days): 0 Min lifetime (hours): 0 Priority: 10 Grace login limit: -1 $ ipa pwpolicy-show --user=user1 Group: ipausers Max lifetime (days): 0 Min lifetime (hours): 0 Grace login limit: -1 $ ipa user-mod user1 --password-expiration=20500101010000Z --------------------- Modified user "user1" --------------------- User login: user1 First name: Userfirst Last name: Userlast Home directory: /home/user1 Login shell: /bin/sh Principal name: user1@<...> Principal alias: user1@<...> User password expiration: 20500101010000Z Email address: user1@<...> UID: 1188200003 GID: 1188200003 Account disabled: False Password: True Member of groups: ipausers Kerberos keys available: True $ passwd Changing password for user user1. Current Password: New password: Retype new password: passwd: all authentication tokens updated successfully. $ ipa user-show user1 --all dn: uid=user1,cn=users,cn=accounts,dc=<...> User login: user1 First name: Userfirst Last name: Userlast Full name: Userfirst Userlast Display name: Userfirst Userlast Initials: UU Home directory: /home/user1 GECOS: Userfirst Userlast Login shell: /bin/sh Principal name: user1@<...> Principal alias: user1@<...> Email address: user1@<...> UID: 1188200003 GID: 1188200003 Account disabled: False Preserved user: False Password: True Member of groups: ipausers Kerberos keys available: True ipantsecurityidentifier: S-1-5-21-<...> ipauniqueid: a4c2c5ce-<...> krblastpwdchange: 20230504065345Z objectclass: top, person, organizationalperson, inetorgperson, inetuser, posixaccount, krbprincipalaux, krbticketpolicyaux, ipaobject, ipasshuser, ipaSshGroupOfPubKeys, mepOriginEntry, ipantuserattrs ============================================================= Version-Release number of selected component (if applicable): # rpm -qa | grep ipa | sort ipa-client-4.10.0-8.el9_1.x86_64 ipa-client-common-4.10.0-8.el9_1.noarch ipa-common-4.10.0-8.el9_1.noarch ipa-healthcheck-core-0.9-9.el9.noarch ipa-selinux-4.10.0-8.el9_1.noarch ipa-server-4.10.0-8.el9_1.x86_64 ipa-server-common-4.10.0-8.el9_1.noarch ipa-server-dns-4.10.0-8.el9_1.noarch How reproducible: 100% Actual results: If "maxlife" is undefined, password expiration is set to 90 days. Expected results: If "maxlife" is undefined, password expiration should be disabled.
There is a default 90-day expiration policy if maxlife is not explicitly defined in the password policy. We can update the pwpolicy module built-in help to reflect this.
90 days = 2160 (90 x 24) hours. If maxlife is undefined, then default 90 will apply. It is still not quite right... # ipa pwpolicy-mod ipausers --maxlife=1 --minlife=25 ipa: ERROR: invalid 'maxlife': Maximum password life must be equal to or greater than the minimum. # ipa pwpolicy-mod ipausers --maxlife=90 --minlife=2161 ipa: ERROR: invalid 'maxlife': Maximum password life must be equal to or greater than the minimum. # ipa pwpolicy-mod ipausers --minlife=2161 Group: ipausers Min lifetime (hours): 2161 Priority: 10 Grace login limit: -1
(In reply to Rob Crittenden from comment #1) > There is a default 90-day expiration policy if maxlife is not explicitly > defined in the password policy. > > We can update the pwpolicy module built-in help to reflect this. Please include usage for both zero and NULL value.
Further testing found that there is discrepancy when applying the default value: 1. User changes its password using `passwd` 2. User changes its password using `ipa user-mod --password <user>` When maxlife is NULL, 90 days will apply in (#1), but unset in (#2). Behaviour of command line `ipa` and WebUI is identical. # ipa pwpolicy-show --user=bob Group: ipausers Grace login limit: -1 ===== $ id uid=1404800003(bob) gid=1404800003(bob) groups=1404800003(bob) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 $ klist Ticket cache: KCM:1404800003:16132 Default principal: bob@<...> Valid starting Expires Service principal 05/09/23 15:09:08 05/10/23 14:38:09 HTTP/node-0.<...>@<...> 05/09/23 15:09:04 05/10/23 14:38:09 krbtgt/<...>@<...> $ passwd Changing password for user bob. Current Password: New password: Retype new password: passwd: all authentication tokens updated successfully. $ ipa user-show bob --all dn: uid=bob,cn=users,cn=accounts,dc=<...> User login: bob First name: Bob Last name: User Full name: Bob User Display name: Bob User Initials: BU Home directory: /home/bob GECOS: Bob User Login shell: /bin/sh Principal name: bob@<...> Principal alias: bob@<...> User password expiration: 20230807051439Z <<<<<===== Email address: bob@<...> UID: 1404800003 GID: 1404800003 Account disabled: False Preserved user: False Password: True Member of groups: ipausers Kerberos keys available: True ipantsecurityidentifier: S-1-5-21-<...> ipauniqueid: 61c13ac8-<...> krblastpwdchange: 20230509051439Z objectclass: top, person, organizationalperson, inetorgperson, inetuser, posixaccount, krbprincipalaux, krbticketpolicyaux, ipaobject, ipasshuser, ipaSshGroupOfPubKeys, mepOriginEntry, ipantuserattrs $ ipa user-mod --password bob Password: Enter Password again to verify: ------------------- Modified user "bob" ------------------- User login: bob First name: Bob Last name: User Home directory: /home/bob Login shell: /bin/sh Principal name: bob@<...> Principal alias: bob@<...> Email address: bob@<...> UID: 1404800003 GID: 1404800003 Account disabled: False Password: True Member of groups: ipausers Kerberos keys available: True $ ipa user-show bob --all dn: uid=bob,cn=users,cn=accounts,dc=<...> User login: bob First name: Bob Last name: User Full name: Bob User Display name: Bob User Initials: BU Home directory: /home/bob GECOS: Bob User Login shell: /bin/sh Principal name: bob@<...> Principal alias: bob@<...> Email address: bob@<...> UID: 1404800003 GID: 1404800003 Account disabled: False Preserved user: False Password: True Member of groups: ipausers Kerberos keys available: True ipantsecurityidentifier: S-1-5-21-<...> ipauniqueid: 61c13ac8-<...> krblastpwdchange: 20230509052130Z objectclass: top, person, organizationalperson, inetorgperson, inetuser, posixaccount, krbprincipalaux, krbticketpolicyaux, ipaobject, ipasshuser, ipaSshGroupOfPubKeys, mepOriginEntry, ipantuserattrs $ passwd Changing password for user bob. Current Password: New password: Retype new password: passwd: all authentication tokens updated successfully. $ ipa user-show bob --all dn: uid=bob,cn=users,cn=accounts,dc=<...> User login: bob First name: Bob Last name: User Full name: Bob User Display name: Bob User Initials: BU Home directory: /home/bob GECOS: Bob User Login shell: /bin/sh Principal name: bob@<...> Principal alias: bob@<...> User password expiration: 20230807052332Z <<<<<===== Email address: bob@<...> UID: 1404800003 GID: 1404800003 Account disabled: False Preserved user: False Password: True Member of groups: ipausers Kerberos keys available: True ipantsecurityidentifier: S-1-5-21-<...> ipauniqueid: 61c13ac8-<...> krblastpwdchange: 20230509052332Z objectclass: top, person, organizationalperson, inetorgperson, inetuser, posixaccount, krbprincipalaux, krbticketpolicyaux, ipaobject, ipasshuser, ipaSshGroupOfPubKeys, mepOriginEntry, ipantuseratt
The difference is the paths that passwd vs ipa passwd take. passwd goes through as a Kerberos password change and ipa passwd is done via LDAP. The backends are necessarily different. The LDAP policy code treats a non-existent value as 0 and Kerberos defaults to 90. I propose the LDAP code also default to 90 if no value is set but still honor if 0 is. And document the 90-day default.
Thank you. Please also review issue described in "comment 2" that "ipa pwpolicy-mod" allows the implicit (default) value of 90 to be added.
@rcritten I just wanted to point out the issue more explicit. One of the constraints is: maxlife must be greater than or equal to minlife. The first command is declined - OK. The second command was executed successfully - Not OK. As "maxlife" has a default value of "90", two commands should have identical effect. However, the latter command does not evaluate default value if omitted, and the constraint is circumvented. (In reply to Sunny Wu from comment #2) > 90 days = 2160 (90 x 24) hours. > > # ipa pwpolicy-mod ipausers --maxlife=90 --minlife=2161 > ipa: ERROR: invalid 'maxlife': Maximum password life must be equal to or > greater than the minimum. > > # ipa pwpolicy-mod ipausers --minlife=2161 > Group: ipausers > Min lifetime (hours): 2161 > Priority: 10 > Grace login limit: -1
Right. Since maxlife is treated as having a default value in the plugin it needs to be an explicit default value in all group policies. This may be disruptive to existing installs that have relied on the old behavior though.