Bug 1590647

Summary: ldapmodify userPassword reflects on krblastpwdchange on RHEL6 but not RHEL7
Product: Red Hat Enterprise Linux 7 Reporter: Ahmed Nazmy <anazmy>
Component: ipaAssignee: IPA Maintainers <ipa-maint>
Status: CLOSED ERRATA QA Contact: ipa-qe <ipa-qe>
Severity: urgent Docs Contact:
Priority: urgent    
Version: 7.5CC: anazmy, cpelland, frenaud, gparente, ndehadra, nsoman, pasik, pvoborni, rcritten, tbordaz, tmihinto, toneata, tscherf
Target Milestone: rcKeywords: ZStream
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: ipa-4.6.4-6.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
: 1615984 (view as bug list) Environment:
Last Closed: 2018-10-30 10:58:39 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1615984    

Description Ahmed Nazmy 2018-06-13 06:22:26 UTC
Description of problem:

In IPA, running ldapmodify as "Directory Manager" against a userpassword reflects on krblastpwdchange, only on RHEL6 but not RHEL7.

Version-Release number of selected component (if applicable):
IPA 3.X
IPA 4.5

How reproducible:
Always

Steps to Reproduce:
1.Setup RHEL6 and RHEL7 IPA
2.Try to modify a userpassword as directory manager:
~~~
ldapmodify -v -Z -h `hostname` -x -D "cn=Directory Manager" -W << EOF
dn: uid=jsmith,cn=users,cn=accounts,dc=example,dc=com
changetype: modify
replace: userPassword
userPassword: apassword
EOF
~~~

3. Check user's krblastpwdchange on both REHL6 and RHEL7:
~~~
# ipa user-show jsmith --all
~~~

Actual results:

krblastpwdchange is updated after password reset on RHEL6 but not on RHEL7.

Expected results:
krblastpwdchange gets updated on RHEL7 in a similar way as RHEL6.

Additional info:

Comment 2 Ahmed Nazmy 2018-06-13 06:25:41 UTC
Looks like binding as admin still reflect the changes as expect, the problem seems only with Directory Manager?

So:
~~~
ldapmodify -v -Z -h `hostname` -x -D "uid=admin,cn=users,cn=accounts,dc=example,dc=com" -W << EOF
dn: uid=jsmith,cn=users,cn=accounts,dc=example,dc=com
changetype: modify
replace: userPassword
userPassword: apassword
EOF
~~~

Will reflect the changes on krbLastPwdChange on RHEL7.

Comment 3 thierry bordaz 2018-06-13 12:31:11 UTC
The change of behavior was introduced in freeipa-3.1.0 with the change f1f1b4e7f2e9c1838ad7ec76002b78ca0c2a3c46.

This change was to make ipa DS plugins TXN-aware.
So plugin pre/post callbacks are called in BE-TXN pre/post, in addition to pre/post.

detailed description:

in ipa-pwd-extop plugin, the callback ipapwd_pre_mod was called in SLAPI_PLUGIN_PRE_MODIFY_FN. with that change it is called in addition in SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN.

In SLAPI_PLUGIN_PRE_MODIFY_FN, the modifiers contains ['userpassword', 'modifytimestamp', 'modifiersname', unhashed#user#password]. The target entry being 'krbPrincipalAux' it generates hashed keys (gen_krb_keys=1) and adds 'krbPrincipalKey' to the modifiers.

Then SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN is called with the modifiers ['userpassword', 'modifytimestamp', 'modifiersname', unhashed#user#password, 'krbPrincipalKey']. Because of two conditions:
  - 'krbPrincipalKey' in the modifiers
  - operation run by DM
It skips (skip_keys=has_krb_keys=1) the update of the: krbPasswordExpiration and krbLastPwdChange.

Note: ipapwd_pre_mod (preop) uses an operation extension to inform the postop (ipapwd_post_modadd) what updates to do


In conclusion:

I think the double call of ipapwd_pre_mod is likely unexpected. ipapwd_pre_mod sets the operation extension based on the modifiers but it also change the modifiers. Also there is similar double call to ipapwd_post_modadd in POST_OP and TXN-BE-POSTOP.

A fix to try could be to remove registration of ipapwd_pre_mod/ipapwd_post_modadd in PREOP/POSTOP

Comment 5 Florence Blanc-Renaud 2018-06-25 15:19:10 UTC
Upstream ticket:
https://pagure.io/freeipa/issue/7601

Comment 27 Nikhil Dehadrai 2018-08-20 08:22:14 UTC
# rpm -q ipa-server 389-ds-base
ipa-server-4.6.4-6.el7.x86_64
389-ds-base-1.3.8.4-10.el7.x86_64

Verified the bug on the basis of following observations:

1. Tested that when a new user is creates and upon first modifying the user password using 'ldapmodify' command the 'krbLastPwdChange' field is updated and so is the 'krbPasswordExpiration' is updated with correct expiration  value.(apprx 90 days in my case) 
(note: here kinit was not run upon user creattion)

[root@vm-idm-038 ~]# ipa user-add --first=test --last=user1 --password
User login [tuser1]: 
Password: 
Enter Password again to verify: 
-------------------
Added user "tuser1"
-------------------
  User login: tuser1
  First name: test
  Last name: user1
  Full name: test user1
  Display name: test user1
  Initials: tu
  Home directory: /home/tuser1
  GECOS: test user1
  Login shell: /bin/sh
  Principal name: tuser1
  Principal alias: tuser1
  User password expiration: 20180817191353Z
  Email address: tuser1
  UID: 315800004
  GID: 315800004
  Password: True
  Member of groups: ipausers
  Kerberos keys available: True
[root@vm-idm-038 ~]# ldapsearch -LLL -Y GSSAPI -b cn=users,cn=accounts,dc=testrelm,dc=test uid=tuser1
SASL/GSSAPI authentication started
SASL username: admin
SASL SSF: 256
SASL data security layer installed.
dn: uid=tuser1,cn=users,cn=accounts,dc=testrelm,dc=test
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=testrelm,dc=test
mepManagedEntry: cn=tuser1,cn=groups,cn=accounts,dc=testrelm,dc=test
krbExtraData:: AAJxHndbcm9vdC9hZG1pbkBURVNUUkVMTS5URVNUAA==
krbLastPwdChange: 20180817191353Z
krbPasswordExpiration: 20180817191353Z
displayName: test user1
uid: tuser1
krbCanonicalName: tuser1
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
loginShell: /bin/sh
initials: tu
gecos: test user1
sn: user1
homeDirectory: /home/tuser1
mail: tuser1
krbPrincipalName: tuser1
givenName: test
cn: test user1
ipaUniqueID: aed20b54-a251-11e8-baad-52540051aff8
uidNumber: 315800004
gidNumber: 315800004

[root@vm-idm-038 ~]# ldapmodify -v -Z -h `hostname` -x -D "cn=Directory Manager" -W << EOF
dn: uid=tuser1,cn=users,cn=accounts,dc=testrelm,dc=test
changetype: modify
replace: userPassword
userPassword: apassword
EOF

ldap_initialize( ldap://vm-idm-038.testrelm.test )
Enter LDAP Password: 
replace userPassword:
	apassword
modifying entry "uid=tuser1,cn=users,cn=accounts,dc=testrelm,dc=test"
modify complete

[root@vm-idm-038 ~]# ldapsearch -LLL -Y GSSAPI -b cn=users,cn=accounts,dc=testrelm,dc=test uid=tuser1
SASL/GSSAPI authentication started
SASL username: admin
SASL SSF: 256
SASL data security layer installed.
dn: uid=tuser1,cn=users,cn=accounts,dc=testrelm,dc=test
krbExtraData:: AAKoHndbcm9vdC9hZG1pbkBURVNUUkVMTS5URVNUAA==
krbLastPwdChange: 20180817191448Z
krbPasswordExpiration: 20181115191448Z
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=testrelm,dc=test
mepManagedEntry: cn=tuser1,cn=groups,cn=accounts,dc=testrelm,dc=test
displayName: test user1
uid: tuser1
krbCanonicalName: tuser1
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
loginShell: /bin/sh
initials: tu
gecos: test user1
sn: user1
homeDirectory: /home/tuser1
mail: tuser1
krbPrincipalName: tuser1
givenName: test
cn: test user1
ipaUniqueID: aed20b54-a251-11e8-baad-52540051aff8
uidNumber: 315800004
gidNumber: 315800004


2. Tested that when a new user is creates and upon first modifying the user password using 'ipa user-mod' command the 'krbLastPwdChange' field is updated and so is the 'krbPasswordExpiration' is updated with SAME value. (note: kinit command was not run for this newly created user).

[root@vm-idm-038 ~]# ipa user-add --first=test --last=user2 --password
User login [tuser2]: 
Password: 
Enter Password again to verify: 
-------------------
Added user "tuser2"
-------------------
  User login: tuser2
  First name: test
  Last name: user2
  Full name: test user2
  Display name: test user2
  Initials: tu
  Home directory: /home/tuser2
  GECOS: test user2
  Login shell: /bin/sh
  Principal name: tuser2
  Principal alias: tuser2
  User password expiration: 20180817193127Z
  Email address: tuser2
  UID: 315800005
  GID: 315800005
  Password: True
  Member of groups: ipausers
  Kerberos keys available: True
[root@vm-idm-038 ~]# ldapsearch -LLL -Y GSSAPI -b cn=users,cn=accounts,dc=testrelm,dc=test uid=tuser2
SASL/GSSAPI authentication started
SASL username: admin
SASL SSF: 256
SASL data security layer installed.
dn: uid=tuser2,cn=users,cn=accounts,dc=testrelm,dc=test
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=testrelm,dc=test
mepManagedEntry: cn=tuser2,cn=groups,cn=accounts,dc=testrelm,dc=test
krbExtraData:: AAKPIndbcm9vdC9hZG1pbkBURVNUUkVMTS5URVNUAA==
krbLastPwdChange: 20180817193127Z
krbPasswordExpiration: 20180817193127Z
displayName: test user2
uid: tuser2
krbCanonicalName: tuser2
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
loginShell: /bin/sh
initials: tu
gecos: test user2
sn: user2
homeDirectory: /home/tuser2
mail: tuser2
krbPrincipalName: tuser2
givenName: test
cn: test user2
ipaUniqueID: 231e01b4-a254-11e8-b446-52540051aff8
uidNumber: 315800005
gidNumber: 315800005

[root@vm-idm-038 ~]# ipa user-mod tuser2 --password
Password: 
Enter Password again to verify: 
----------------------
Modified user "tuser2"
----------------------
  User login: tuser2
  First name: test
  Last name: user2
  Home directory: /home/tuser2
  Login shell: /bin/sh
  Principal name: tuser2
  Principal alias: tuser2
  Email address: tuser2
  UID: 315800005
  GID: 315800005
  Account disabled: False
  Password: True
  Member of groups: ipausers
  Kerberos keys available: True
[root@vm-idm-038 ~]# ldapsearch -LLL -Y GSSAPI -b cn=users,cn=accounts,dc=testrelm,dc=test uid=tuser2
SASL/GSSAPI authentication started
SASL username: admin
SASL SSF: 256
SASL data security layer installed.
dn: uid=tuser2,cn=users,cn=accounts,dc=testrelm,dc=test
krbExtraData:: AALIIndbcm9vdC9hZG1pbkBURVNUUkVMTS5URVNUAA==
krbLastPwdChange: 20180817193224Z
krbPasswordExpiration: 20180817193224Z
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=testrelm,dc=test
mepManagedEntry: cn=tuser2,cn=groups,cn=accounts,dc=testrelm,dc=test
displayName: test user2
uid: tuser2
krbCanonicalName: tuser2
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
loginShell: /bin/sh
initials: tu
gecos: test user2
sn: user2
homeDirectory: /home/tuser2
mail: tuser2
krbPrincipalName: tuser2
givenName: test
cn: test user2
ipaUniqueID: 231e01b4-a254-11e8-b446-52540051aff8
uidNumber: 315800005
gidNumber: 315800005

3. But once the kinit command is run for the user created in step2, then the ''krbPasswordExpiration' is correctly updated (apprx 90 days in my case) 

[root@vm-idm-038 ~]# kinit tuser2
Password for tuser2: 
Password expired.  You must change it now.
Enter new password: 
Enter it again: 
[root@vm-idm-038 ~]# ldapsearch -LLL -Y GSSAPI -b cn=users,cn=accounts,dc=testrelm,dc=test uid=tuser2
SASL/GSSAPI authentication started
SASL username: tuser2
SASL SSF: 256
SASL data security layer installed.
dn: uid=tuser2,cn=users,cn=accounts,dc=testrelm,dc=test
krbPasswordExpiration: 20181115193259Z
krbLastPwdChange: 20180817193259Z
memberOf: cn=ipausers,cn=groups,cn=accounts,dc=testrelm,dc=test
displayName: test user2
uid: tuser2
krbCanonicalName: tuser2
objectClass: top
objectClass: person
objectClass: organizationalperson
objectClass: inetorgperson
objectClass: inetuser
objectClass: posixaccount
objectClass: krbprincipalaux
objectClass: krbticketpolicyaux
objectClass: ipaobject
objectClass: ipasshuser
objectClass: ipaSshGroupOfPubKeys
objectClass: mepOriginEntry
loginShell: /bin/sh
initials: tu
gecos: test user2
sn: user2
homeDirectory: /home/tuser2
mail: tuser2
krbPrincipalName: tuser2
givenName: test
cn: test user2
ipaUniqueID: 231e01b4-a254-11e8-b446-52540051aff8
uidNumber: 315800005
gidNumber: 315800005


4. Upon user deletion no record is found for the user.

[root@vm-idm-038 ~]# ipa user-del tuser2
---------------------
Deleted user "tuser2"
---------------------
[root@vm-idm-038 ~]# ldapsearch -LLL -Y GSSAPI -b cn=users,cn=accounts,dc=testrelm,dc=test uid=tuser2
SASL/GSSAPI authentication started
SASL username: admin
SASL SSF: 256
SASL data security layer installed.
[root@vm-idm-038 ~]# ipa user-find tuser2
---------------
0 users matched
---------------
----------------------------
Number of entries returned 0
----------------------------
[root@vm-idm-038 ~]# 


Thus on the basis of above observations and comment#26 ,marking the status of the bug as 'VERIFIED'.

Comment 30 errata-xmlrpc 2018-10-30 10:58:39 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2018:3187