Bug 31429 - k5pwd overlay doesn't work if account expires
k5pwd overlay doesn't work if account expires
Status: CLOSED FIXED
Product: UCS
Classification: Unclassified
Component: LDAP
UCS 3.2
Other Linux
: P5 normal (vote)
: UCS 3.2-5-errata
Assigned To: Stefan Gohmann
Felix Botner
:
Depends on:
Blocks: 38060
  Show dependency treegraph
 
Reported: 2013-05-23 11:18 CEST by Ingo Steuwer
Modified: 2015-03-25 14:03 CET (History)
5 users (show)

See Also:
What kind of report is it?: ---
What type of bug is this?: ---
Who will be affected by this bug?: ---
How will those affected feel about the bug?: ---
User Pain:
Enterprise Customer affected?:
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ingo Steuwer univentionstaff 2013-05-23 11:18:55 CEST
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
----------------------------------------------------
Comment 1 Ingo Steuwer univentionstaff 2015-02-20 12:09:38 CET
reported by customer, see 2014091721000281
Comment 2 Tim Petersen univentionstaff 2015-02-23 09:33:44 CET
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
Comment 3 Tim Petersen univentionstaff 2015-02-23 09:42:52 CET
Reproduced like described with UCS 3.2-4-e257
Comment 4 Tim Petersen univentionstaff 2015-02-23 15:59:28 CET
(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...
Comment 5 Tim Petersen univentionstaff 2015-02-24 09:21:47 CET
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;
Comment 6 Arvid Requate univentionstaff 2015-02-24 11:58:18 CET
Yeah, that was my initial impression too, we schould check those lines, they came from the original smbkrb5 overlay.
Comment 7 Stefan Gohmann univentionstaff 2015-03-17 12:18:53 CET
(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.
Comment 8 Stefan Gohmann univentionstaff 2015-03-17 13:45:24 CET
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)
Comment 9 Felix Botner univentionstaff 2015-03-24 10:01:05 CET
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
Comment 10 Janek Walkenhorst univentionstaff 2015-03-25 14:03:17 CET
<http://errata.univention.de/ucs/3.2/301.html>