Univention Bugzilla – Bug 31429
k5pwd overlay doesn't work if account expires
Last modified: 2015-03-25 14:03:17 CET
If the last password change occured by Keberos/Samba4/Windows (userPassword={K5KEY}), ldap-bind against slapd fails if the account has an expiry-Date: ---------------------------------------------------- root@dcm:~# univention-ldapsearch uid=accounttest2 userpassword -LLL|ldapsearch-wrapper|ldapsearch-decode64 dn: uid=accounttest2,cn=users,dc=s4sites,dc=local userPassword: {K5KEY} root@dcm:~# udm users/user modify --dn uid=accounttest2,cn=users,dc=s4sites,dc=local --set userexpiry=2014-05-31 Object modified: uid=accounttest2,cn=users,dc=s4sites,dc=local root@dcm:~# ldapsearch -x -h dcm -p 7389 -D "uid=accounttest2,cn=users,dc=s4sites,dc=local" -w Herbert.123 uid=accounttest2 uid ldap_bind: Invalid credentials (49) root@dcm:~# udm users/user modify --dn uid=accounttest2,cn=users,dc=s4sites,dc=local --set userexpiry= Object modified: uid=accounttest2,cn=users,dc=s4sites,dc=local root@dcm:~# ldapsearch -x -h dcm -p 7389 -D "uid=accounttest2,cn=users,dc=s4sites,dc=local" -w Herbert.123 uid=accounttest2 uid -LLL dn: uid=accounttest2,cn=users,dc=s4sites,dc=local uid: accounttest2 ----------------------------------------------------
reported by customer, see 2014091721000281
Works at least with UCS 4.0-1. 1. samba-tool user password -U mailuser 2. verified, that userPassword contains {K5KEY} 3. udm users/user modify --dn uid=mailuser,cn=users,dc=tim,dc=ucs4 --set userexpiry=2015-06-01 4. ldapsearch -x -h master -p 7389 -D "uid=mailuser,cn=users,dc=tim,dc=ucs4" -w Univention123 -s base 5. works
Reproduced like described with UCS 3.2-4-e257
(In reply to Tim Petersen from comment #3) > Reproduced like described with UCS 3.2-4-e257 Seems to be fixed in UCS 4.0-1 and 4.0-0-current Errata - I have no clue where and why yet. But with some debug I found out that k5pwd overlay module says the account is expired. It happens here (k5pwd.c): " + a = attr_find( e->e_attrs, ad_krb5ValidEnd ); + if (a) { + struct lutil_tm tm; + struct lutil_timet tt; + if ( lutil_parsetime( a->a_vals[0].bv_val, &tm ) == 0 && + lutil_tm2time( &tm, &tt ) == 0 && tt.tt_usec < op->o_time ) { + /* Account is expired */ + rc = LUTIL_PASSWD_ERR; + break; + } " if ( lutil_parsetime( a->a_vals[0].bv_val, &tm ) == 0 && lutil_tm2time( &tm, &tt ) == 0 && tt.tt_usec < op->o_time seems to return a wrong result. I don't know exactly what is compared there with krb5ValidEnd. krb5ValidEnd is 20150601000000Z But this attribute didn't change to 4.0-1 .... still it works then. I changed tt.tt_usec in the above statement to tt.tt_sec - now it works... just an assumption...
I am quite sure that the if condition is wrong. ad_krb5ValidEnd contains a ldap year timestamp (20150601000000Z). The code does the following with it: lutil_parsetime( a->a_vals[0].bv_val, &tm ) lutil_tm2time( &tm, &tt ) and then checks: tt.tt_usec < op->o_time -> compare milliseconds with current time since epoch? I don't think so... On system where the behaviour occurs the values look like this: Feb 24 08:20:00 master slapd[17176]: Account is expired Feb 24 08:20:00 master slapd[17176]: ValidEnd: conn=1002 op=0, 9729342 Feb 24 08:20:00 master slapd[17176]: lutil_parsetime( a->a_vals[0].bv_val, &tm ): conn=1002 op=0, 0 Feb 24 08:20:00 master slapd[17176]: lutil_tm2time( &tm, &tt ): conn=1002 op=0, 0 Feb 24 08:20:00 master slapd[17176]: tm.tm_usec: conn=1002 op=0, 9688976 Feb 24 08:20:00 master slapd[17176]: tt.tt_usec: conn=1002 op=0, 9688976 Feb 24 08:20:00 master slapd[17176]: op->o_time: conn=1002 op=0, 1424762400 On systems where the behaviour does not occur (UCS 4.0 with current erratum - I didn't find the concrete cause) it looks like this: Feb 24 09:08:16 master slapd[27119]: Account is not expired Feb 24 09:08:16 master slapd[27119]: ValidEnd: conn=1002 op=0, -188777932 Feb 24 09:08:16 master slapd[27119]: lutil_parsetime( a->a_vals[0].bv_val, &tm ): conn=1002 op=0, 0 Feb 24 09:08:16 master slapd[27119]: lutil_tm2time( &tm, &tt ): conn=1002 op=0, 0 Feb 24 09:08:16 master slapd[27119]: tm.tm_usec: conn=1002 op=0, -214710768 Feb 24 09:08:16 master slapd[27119]: tt.tt_usec: conn=1002 op=0, -214710768 Feb 24 09:08:16 master slapd[27119]: op->o_time: conn=1002 op=0, 1424765296 I am very sure, that it only works per accident. But nevertheless somehow the following code creates different results, comparing current erratums with older ones: a = attr_find( e->e_attrs, ad_krb5ValidEnd ); a->a_vals[0].bv_val;
Yeah, that was my initial impression too, we schould check those lines, they came from the original smbkrb5 overlay.
(In reply to Tim Petersen from comment #5) > and then checks: tt.tt_usec < op->o_time > -> compare milliseconds with current time since epoch? I don't think so... Yes, that's the problem. The struct also has a value for the seconds (tt.tt_sec). > Works at least with UCS 4.0-1. > > 1. samba-tool user password -U mailuser > 2. verified, that userPassword contains {K5KEY} > 3. udm users/user modify --dn uid=mailuser,cn=users,dc=tim,dc=ucs4 --set > userexpiry=2015-06-01 > 4. ldapsearch -x -h master -p 7389 -D "uid=mailuser,cn=users,dc=tim,dc=ucs4" > -w Univention123 -s base > 5. works Not really. The search also succeeded if the expiry was set to the past.
YAML: dev/branches/ucs-3.2/ucs-3.2-5/doc/errata/staging/2015-03-17-openldap.yaml Fix: r14489 Test case: 10_ldap/05K5KEY_userexpiry (r59099)
OLD: -> univention-ldapsearch -LLL uid=test1 userpassword| ldapsearch-decode64 dn: uid=test1,cn=users,dc=fb,dc=intranet userPassword: {K5KEY} -> udm users/user modify --dn uid=test1,cn=users,dc=fb,dc=intranet --set userexpiry=2016-05-31 -> univention-ldapsearch -D uid=test1,cn=users,dc=fb,dc=intranet -w univention ldap_bind: Invalid credentials (49) NEW: # expiry in the future -> udm users/user modify --dn uid=test1,cn=users,dc=fb,dc=intranet --set userexpiry=2016-05-31 Object modified: uid=test1,cn=users,dc=fb,dc=intranet -> univention-ldapsearch -LLL -D uid=test1,cn=users,dc=fb,dc=intranet -w univention uid=test1 dn dn: uid=test1,cn=users,dc=fb,dc=intranet # expiry in the past -> udm users/user modify --dn uid=test1,cn=users,dc=fb,dc=intranet --set userexpiry=2011-05-31 Object modified: uid=test1,cn=users,dc=fb,dc=intranet -> univention-ldapsearch -LLL -D uid=test1,cn=users,dc=fb,dc=intranet -w univention uid=test1 dn ldap_bind: Invalid credentials (49) # no expiry date -> udm users/user modify --dn uid=test1,cn=users,dc=fb,dc=intranet --set userexpiry= Object modified: uid=test1,cn=users,dc=fb,dc=intranet -> univention-ldapsearch -LLL -D uid=test1,cn=users,dc=fb,dc=intranet -w univention uid=test1 dn dn: uid=test1,cn=users,dc=fb,dc=intranet OK - 2015-03-17-openldap.yaml
<http://errata.univention.de/ucs/3.2/301.html>