Bug 971303 - Password set for new user should expire immediately but it does not for one second
Password set for new user should expire immediately but it does not for one s...
Status: CLOSED CURRENTRELEASE
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: ipa (Show other bugs)
7.0
Unspecified Unspecified
medium Severity unspecified
: rc
: 7.0
Assigned To: Rob Crittenden
Namita Soman
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2013-06-06 05:02 EDT by Jan Pazdziora
Modified: 2014-06-17 20:09 EDT (History)
4 users (show)

See Also:
Fixed In Version: ipa-3.2.1-1.el7
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2014-06-13 08:49:26 EDT
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Jan Pazdziora 2013-06-06 05:02:20 EDT
Description of problem:

The documentation in 5.4. Changing Passwords of Identity Management Guide https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html-single/Identity_Management_Guide/index.html#changing-pwds says:

   Changing a password as the IdM admin user overrides any IdM password policies, but the password expires immediately. This requires the user to change the password at the next login.

However, there seems to be a one second race condition when this is not true -- either the expiration is set in the future or the expiration is incorrectly compared.

Version-Release number of selected component (if applicable):

# rpm -qf /usr/bin/ipa /usr/bin/kinit
ipa-admintools-3.0.0-25.el6.x86_64
krb5-workstation-1.10.3-10.el6.x86_64

How reproducible:

Not deterministic but on fast machine very probable.

Steps to Reproduce:
1. kinit as admin so that ipa user-add passes.
2. Set environment variable to yet nonexistent IPA user: export GUSER=test1
3. Run the following script:

date
( echo initpass ; echo initpass ) | ipa user-add $GUSER --first X --last Y --password
echo fk8hAfT7i | kinit $GUSER
klist
date

Actual results:

Thu Jun  6 04:54:11 EDT 2013
------------------
Added user "test1"
------------------
  User login: test1
  First name: X
  Last name: Y
  Full name: X Y
  Display name: X Y
  Initials: XY
  Home directory: /home/test1
  GECOS field: X Y
  Login shell: /bin/sh
  Kerberos principal: test1@TESTRELM.COM
  Email address: test1@testrelm.com
  UID: 835400026
  GID: 835400026
  Password: True
  Kerberos keys available: True
Password for test1@TESTRELM.COM: 
Warning: Your password will expire in less than one hour on Thu Jun  6 04:54:11 2013
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: test1@TESTRELM.COM

Valid starting     Expires            Service principal
06/06/13 04:54:11  06/07/13 04:54:11  krbtgt/TESTRELM.COM@TESTRELM.COM
Thu Jun  6 04:54:11 EDT 2013

Note that the Warning message says that the password "will" expire in 04:54:11 when it already is 04:54:11, and we were able to kinit without changing the password. Sometimes the Warning message is not even shown.

Expected results:

  Kerberos keys available: True
Password for test1@TESTRELM.COM: 
Password expired.  You must change it now.
Enter new password: 
kinit: Cannot read password while getting initial credentials
Ticket cache: FILE:/tmp/krb5cc_0
Default principal: admin@TESTRELM.COM

which is what you get when sleep 1 is added between that user-add and kinit.

Additional info:

When the commands are run by a human, there will likely always be one second between the two events. But in automated / scripted environments, this nondeterminism is not that great and it possibly reveals some issue with the timestamp calculations.
Comment 2 Martin Kosek 2013-06-06 05:46:33 EDT
We should probably update ipa-pwd-extop to set krbpasswordexpiration one second in the past instead of current time. Simo/Rob, any objections?

In any case, I will create a ticket as this behavior is not correct.
Comment 3 Martin Kosek 2013-06-06 05:49:05 EDT
Upstream ticket:
https://fedorahosted.org/freeipa/ticket/3696
Comment 4 Simo Sorce 2013-06-06 09:12:22 EDT
Given kerberos allows for clock skews of 5 minutes, we could use that as a 'standard' skew and set the expiration back 5 minutes. This would certainly avoid any race and also tools running on a different machine directly checking the expiartion time attribute for whatever reason (monitoring, notifying, ...) would not be fooled.

However putting it back even just 1 second is fine by me.
Comment 5 Martin Kosek 2013-06-06 09:19:14 EDT
Good idea, 5 minutes sounds fine. I will update the upstream ticket.
Comment 6 Jan Pazdziora 2013-06-06 09:22:34 EDT
What I wonder is -- if the expiration is set as YYYY-MM-DD HH:MI:SS, does it mean it expires at HH:MI:SS.000000, or at HH:MI:SS.999999? Isn't the expiry check which is wrong (using possibly something like "greater than", when it should be using "grater or equal")?
Comment 7 Simo Sorce 2013-06-06 09:31:30 EDT
Excellent point Jan.

We do never check for equality in our expiration time checks, neither for password expiration nor for account expiration.

So you are correct that the current bug could be strictly solved by a >= or <= instead of the current > or <

This is also a valid solution to this bug.
Comment 8 Martin Kosek 2013-06-12 11:49:18 EDT
We found out that this Bugzilla is a duplicate of upstream ticket https://fedorahosted.org/freeipa/ticket/1064. Upstream commit:
master: bf77679909c3d73aea77f3ededd8d84e3c045d44

As this is not a critical issue, I do not think it needs to be fixed in RHEL-6.

Moving to RHEL-7.0 where it will be fixed as part of IPA package rebase.
Comment 10 Martin Kosek 2013-06-17 09:37:51 EDT
Moving to POST, this is fixed upstream:
master: bf77679909c3d73aea77f3ededd8d84e3c045d44
Comment 13 Michael Gregg 2014-01-29 17:28:32 EST
Verified against ipa-server-3.3.3-12.el7.x86_64

[root@zippyvm8 ~]# date
Wed Jan 29 17:27:11 EST 2014
[root@zippyvm8 ~]# ( echo initpass ; echo initpass ) | ipa user-add $GUSER --first X --last Y --password
ipa: ERROR: user with name "newguser" already exists
[root@zippyvm8 ~]# echo fk8hAfT7i | kinit $GUSER
Password for newguser@EXAMPLE.COM: 
kinit: Password incorrect while getting initial credentials
[root@zippyvm8 ~]# klist
Ticket cache: KEYRING:persistent:0:0
Default principal: admin@EXAMPLE.COM

Valid starting       Expires              Service principal
01/29/2014 17:26:29  01/30/2014 17:25:42  HTTP/zippyvm8.idm.lab.eng.rdu2.redhat.com@EXAMPLE.COM
01/29/2014 17:25:45  01/30/2014 17:25:42  krbtgt/EXAMPLE.COM@EXAMPLE.COM
[root@zippyvm8 ~]# date;
Wed Jan 29 17:27:12 EST 2014

To be automated.
Comment 14 Michael Gregg 2014-02-25 13:07:20 EST
I believe the original script that I used to verify wasn't quite correct to verify this bug with. 

This time, I attempted to kinit as the user with the original password that admin set for the user. If this bug is correct, then the kinit should ask for a new password. It does. 

Bug still verified. 

[root@ipaqa64vmb ~]# date;( echo initpass ; echo initpass ) | ipa user-add $GUSER --first X --last Y --password; kdestroy; echo initpass | kinit $GUSER; date
Tue Feb 25 13:05:10 EST 2014
---------------------
Added user "newguser"
---------------------
  User login: newguser
  First name: X
  Last name: Y
  Full name: X Y
  Display name: X Y
  Initials: XY
  Home directory: /home/newguser
  GECOS: X Y
  Login shell: /bin/sh
  Kerberos principal: newguser@TESTRELM.TEST
  Email address: newguser@testrelm.test
  UID: 1998800003
  GID: 1998800003
  Password: True
  Member of groups: ipausers
  Kerberos keys available: True
Password for newguser@TESTRELM.TEST: 
Password expired.  You must change it now.
Enter new password: 
kinit: Cannot read password while getting initial credentials
Tue Feb 25 13:05:10 EST 2014
Comment 15 Martin Kosek 2014-02-25 16:00:37 EST
Thanks, this is closer to valid verification (you received the key error message "Password expired.  You must change it now.").

I assume you intentionally pass the insufficient data for kinit with expired passwords so that it fails:

Password for newguser@TESTRELM.TEST: 
Password expired.  You must change it now.
Enter new password: 
kinit: Cannot read password while getting initial credentials

Note that to kinit properly even with expired passwords, you would need to run:

# echo -e 'initpass\nnew_pwd123\nnew_pwd123' | kinit newguser

... to also verify that the expiration password change completes.
Comment 16 Michael Gregg 2014-02-25 16:19:29 EST
I may need to unverify this bug. 

In comment #4 and comment #5, it looks like a decision was made to set the expiry time back 5 min from when the password is set by the admin. 

In this example, I set the password for $tuser, then, I expect that the expiration time for that user would be this time minus 5 min. So, I set the clock back 3 min, and then kinit as the user. This works. 

[root@nocp7 ~]# date; echo 'passwd' | ipa passwd $tuser
Tue Feb 25 16:09:10 EST 2014
-----------------------------------------
Changed password for "lljk@TESTRELM.TEST"
-----------------------------------------

[root@nocp7 ~]# kdestroy 
[root@nocp7 ~]# date -s '3 minutes ago'
Tue Feb 25 16:06:28 EST 2014
[root@nocp7 ~]# kinit $tuser
Password for lljk@TESTRELM.TEST: 
Warning: Your password will expire in less than one hour on Tue 25 Feb 2014 04:09:10 PM EST


The password expiration time is set to the same time as when the password was set (Tue Feb 25 16:09:10 EST 2014), but shouldn't the expiration time be set to 5 min earlier as per comment #4 and #5?
Comment 17 Rob Crittenden 2014-02-25 18:32:22 EST
The time isn't set back 5 minutes, it is set back 1 second:

--- a/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c
+++ b/daemons/ipa-slapi-plugins/ipa-pwd-extop/ipapwd_common.c
@@ -640,6 +640,12 @@ int ipapwd_CheckPolicy(struct ipapwd_data *data)
          * force a password change on the next login.
          * But not if Directory Manager */
         if (data->changetype == IPA_CHANGETYPE_ADMIN) {
+            /* The expiration date needs to be older than the current time
+             * otherwise the KDC may not immediately register the password
+             * as expired. The last password change needs to match the
+             * password expiration otherwise minlife issues will arise.
+             */
+            data->timeNow -= 1;
             data->expireTime = data->timeNow;
         }
Comment 18 Michael Gregg 2014-02-25 18:53:40 EST
I will alter the automated test to verify the expiration time is set to 1 second instead of 300 seconds.
Comment 19 Ludek Smid 2014-06-13 08:49:26 EDT
This request was resolved in Red Hat Enterprise Linux 7.0.

Contact your manager or support representative in case you have further questions about the request.

Note You need to log in before you can comment on or make changes to this bug.