Issue 9279 - Support for Netscape password expiry controls
Summary: Support for Netscape password expiry controls
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: overlays (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: 2.4.51
Assignee: Ondřej Kuzník
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-06-23 10:44 UTC by Ondřej Kuzník
Modified: 2020-08-19 16:23 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Ondřej Kuzník 2020-06-23 10:44:23 UTC
Add support for legacy clients expecting the LDAP server to attach these controls on relevant bind responses:
- Password Expired Control (2.16.840.1.113730.3.4.4)
- Password Expiration Warning Control (2.16.840.1.113730.3.4.5)

Decisions as configured by regular password policy.
Comment 1 Quanah Gibson-Mount 2020-07-22 23:18:22 UTC
RE24:

Commits: 
  • 0687e289 
by Ondřej Kuzník at 2020-07-22T22:11:44+00:00 
ITS#9279 Expose Netscape password policy controls in libldap


  • 094848b6 
by Ondřej Kuzník at 2020-07-22T22:11:44+00:00 
ITS#9279 Implement Netscape password policy controls in ppolicy
Comment 2 Quanah Gibson-Mount 2020-07-22 23:18:43 UTC
master:

Commits: 
  • fd921e71 
by Ondřej Kuzník at 2020-07-22T18:57:38+00:00 
ITS#9279 Expose Netscape password policy controls in libldap


  • a49b5536 
by Ondřej Kuzník at 2020-07-22T18:57:38+00:00 
ITS#9279 Implement Netscape password policy controls in ppolicy
Comment 3 Michael Ströder 2020-07-25 17:53:40 UTC
I've added a test for these response controls to python-ldap0 (branch):

https://gitlab.com/ae-dir/python-ldap0/-/tree/its9279

But it seems to fail with wrong response OID for password expiration warning:

DEBUG:root:<ldap0.ldapobject.LDAPObject object at 0x7f7ea896bc10> ldap://127.0.0.1:42853 - LDAPObject.result(((1, 1, -1, True, False, False), {}))
5f1c70f0 ppolicy_bind: Setting warning for password expiry for cn=user1,o=öäü,dc=example,dc=org = 1 seconds
5f1c70f0 conn=1011 op=0 RESULT tag=97 err=0 text=
DEBUG:root:-> (97, [], 1, [(b'2.16.840.1.113730.3.4.4', 0, b'\x04\x010')])
[..]
AssertionError: <ldap0.controls.pwdpolicy.PasswordExpiredControl object at 0x7f7ea8946a00> is not an instance of <class 'ldap0.controls.pwdpolicy.PasswordExpiringControl'>
Comment 4 Michael Ströder 2020-07-26 11:40:47 UTC
Was this actually tested with one of the legacy clients making use of that?

I have some doubts about using LBER_USE_DER.

Because I've searched in my old python-ldap mailing list archive and found that with other server implementations controlValue of 2.16.840.1.113730.3.4.5 consists just of ASCII digits representing grace period in seconds.

And IIRC controlValue of 2.16.840.1.113730.3.4.4 is also just a single digit "0" without OctetString wrapping. See also my inquiry to ietf-ldapext mailing list:

https://mailarchive.ietf.org/arch/msg/ldapext/jBnnQxBngfYUD8A2RLeI1tAVb5M

Note that many moons ago I had test servers when implementing this in python-ldap. IIRC it was OpenDJ.

I've recently added automated tests for that in python-ldap0:

https://gitlab.com/ae-dir/python-ldap0/-/blob/master/tests/test_ppolicy.py#L237
Comment 5 Michael Ströder 2020-07-26 11:48:41 UTC
(In reply to Michael Ströder from comment #4)
> I've searched in my old python-ldap mailing list archive

https://mail.python.org/pipermail/python-ldap/2014q1/003342.html

Unfortunately the referenced OpenDJ mailing list archive is not available anymore. But there's a copy of the 3-message thread:

https://marc.info/?t=139603531900011&r=1&w=2
Comment 6 Michael Ströder 2020-07-26 16:12:55 UTC
(In reply to Michael Ströder from comment #4)
> See also my inquiry to ietf-ldapext
> mailing list:
> 
> https://mailarchive.ietf.org/arch/msg/ldapext/jBnnQxBngfYUD8A2RLeI1tAVb5M

Neil's response is pretty clear:

https://mailarchive.ietf.org/arch/msg/ldapext/_J2wBksnlCYbemmf3bTanCDAXuA

No DER, just ASCII digits in a byte-sequence. Yes, it's legacy stuff.
Comment 7 Quanah Gibson-Mount 2020-07-27 17:39:32 UTC
  • 917fcc03 
by Ondřej Kuzník at 2020-07-27T14:22:24+02:00 
ITS#9279 Send Netscape expired control as a bare string
Comment 8 Quanah Gibson-Mount 2020-07-27 17:40:41 UTC
RE24:

  • 98937068 
by Ondřej Kuzník at 2020-07-27T17:39:52+00:00 
ITS#9279 Send Netscape expired control as a bare string
Comment 9 Michael Ströder 2020-07-27 18:11:44 UTC
(In reply to Quanah Gibson-Mount from comment #8)
> RE24:
> 
>   • 98937068 
> by Ondřej Kuzník at 2020-07-27T17:39:52+00:00 
> ITS#9279 Send Netscape expired control as a bare string

This indeed fixed password expired response test in python-ldap0:

https://gitlab.com/ae-dir/python-ldap0/-/commit/39bf9d98fc794677d9639053ccadfe2ae1c8dbc0
Comment 10 Michael Ströder 2020-07-27 18:12:54 UTC
(In reply to Michael Ströder from comment #3)
> But it seems to fail with wrong response OID for password expiration warning:
> [..]
> AssertionError: <ldap0.controls.pwdpolicy.PasswordExpiredControl object at
> 0x7f7ea8946a00> is not an instance of <class
> 'ldap0.controls.pwdpolicy.PasswordExpiringControl'>

This bug is still not fixed.
Comment 11 Quanah Gibson-Mount 2020-07-27 18:14:36 UTC
(In reply to Michael Ströder from comment #10)
> (In reply to Michael Ströder from comment #3)
> > But it seems to fail with wrong response OID for password expiration warning:
> > [..]
> > AssertionError: <ldap0.controls.pwdpolicy.PasswordExpiredControl object at
> > 0x7f7ea8946a00> is not an instance of <class
> > 'ldap0.controls.pwdpolicy.PasswordExpiringControl'>
> 
> This bug is still not fixed.

Ondrej :)
Comment 12 Howard Chu 2020-07-30 16:30:24 UTC
(In reply to Michael Ströder from comment #10)
> (In reply to Michael Ströder from comment #3)
> > But it seems to fail with wrong response OID for password expiration warning:
> > [..]
> > AssertionError: <ldap0.controls.pwdpolicy.PasswordExpiredControl object at
> > 0x7f7ea8946a00> is not an instance of <class
> > 'ldap0.controls.pwdpolicy.PasswordExpiringControl'>
> 
> This bug is still not fixed.

Can you please test with this patch?

https://git.openldap.org/hyc/openldap/-/commits/its9279

Thanks
Comment 13 Michael Ströder 2020-07-30 18:45:37 UTC
(In reply to Howard Chu from comment #12)
> Can you please test with this patch?
> https://git.openldap.org/hyc/openldap/-/commits/its9279

Can I just back-port this diff to RE24?

https://git.openldap.org/hyc/openldap/-/commit/dae146b251673d8a668a465e13f9671ae4fffa9a
Comment 14 Quanah Gibson-Mount 2020-07-30 18:51:23 UTC
(In reply to Michael Ströder from comment #13)
> (In reply to Howard Chu from comment #12)
> > Can you please test with this patch?
> > https://git.openldap.org/hyc/openldap/-/commits/its9279
> 
> Can I just back-port this diff to RE24?
> 
> https://git.openldap.org/hyc/openldap/-/commit/
> dae146b251673d8a668a465e13f9671ae4fffa9a

Yes.
Comment 15 Michael Ströder 2020-07-30 20:17:31 UTC
(In reply to Quanah Gibson-Mount from comment #14)
> (In reply to Michael Ströder from comment #13)
> > (In reply to Howard Chu from comment #12)
> > > Can you please test with this patch?
> > > https://git.openldap.org/hyc/openldap/-/commits/its9279
> > 
> > Can I just back-port this diff to RE24?
> > 
> > https://git.openldap.org/hyc/openldap/-/commit/
> > dae146b251673d8a668a465e13f9671ae4fffa9a
> 
> Yes.

It does not work:

5f232451 conn=1011 op=0 BIND dn="cn=user1,o=öäü,dc=example,dc=org" mech=SIMPLE ssf=0
5f232451 ppolicy_bind: Setting warning for password expiry for cn=user1,o=öäü,dc=example,dc=org = 1 seconds
DEBUG:root:<ldap0.ldapobject.LDAPObject object at 0x7f5210212a60> ldap://127.0.0.1:35171 - LDAPObject.result(((1, 1, -1, True, False, False), {}))
5f232451 conn=1011 op=0 RESULT tag=97 err=0 text=
DEBUG:root:-> (97, [], 1, [(b'2.16.840.1.113730.3.4.4', 0, b'0')])
DEBUG:root:bind_res = LDAPResult(97, [], 1, [<ldap0.controls.pwdpolicy.PasswordExpiredControl object at 0x7f52101eba30>])

I've checked my test code whether there's a timing problem. But slapo-ppolicy logs "Setting warning for password expiry" and so I assume the test code is correct.
Comment 16 Howard Chu 2020-07-31 00:44:03 UTC
(In reply to Michael Ströder from comment #10)
> (In reply to Michael Ströder from comment #3)
> > But it seems to fail with wrong response OID for password expiration warning:
> > [..]
> > AssertionError: <ldap0.controls.pwdpolicy.PasswordExpiredControl object at
> > 0x7f7ea8946a00> is not an instance of <class
> > 'ldap0.controls.pwdpolicy.PasswordExpiringControl'>
> 
> This bug is still not fixed.

Can you please test with this patch?

https://git.openldap.org/hyc/openldap/-/commits/its9279

Thanks(In reply to Michael Ströder from comment #15)
> (In reply to Quanah Gibson-Mount from comment #14)
> > (In reply to Michael Ströder from comment #13)
> > > (In reply to Howard Chu from comment #12)
> > > > Can you please test with this patch?
> > > > https://git.openldap.org/hyc/openldap/-/commits/its9279
> > > 
> > > Can I just back-port this diff to RE24?
> > > 
> > > https://git.openldap.org/hyc/openldap/-/commit/
> > > dae146b251673d8a668a465e13f9671ae4fffa9a
> > 
> > Yes.
> 
> It does not work:
> 
> 5f232451 conn=1011 op=0 BIND dn="cn=user1,o=öäü,dc=example,dc=org"
> mech=SIMPLE ssf=0
> 5f232451 ppolicy_bind: Setting warning for password expiry for
> cn=user1,o=öäü,dc=example,dc=org = 1 seconds
> DEBUG:root:<ldap0.ldapobject.LDAPObject object at 0x7f5210212a60>
> ldap://127.0.0.1:35171 - LDAPObject.result(((1, 1, -1, True, False, False),
> {}))
> 5f232451 conn=1011 op=0 RESULT tag=97 err=0 text=
> DEBUG:root:-> (97, [], 1, [(b'2.16.840.1.113730.3.4.4', 0, b'0')])
> DEBUG:root:bind_res = LDAPResult(97, [], 1,
> [<ldap0.controls.pwdpolicy.PasswordExpiredControl object at 0x7f52101eba30>])
> 
> I've checked my test code whether there's a timing problem. But
> slapo-ppolicy logs "Setting warning for password expiry" and so I assume the
> test code is correct.

I cannot confirm the error you're seeing. I've extended test022-ppolicy in our test suite and am definitely seeing the correct Warning control before expiration, and the correct Expired control after expiration.
Comment 17 Quanah Gibson-Mount 2020-08-03 22:33:59 UTC
I tried building python-ldap0 to see if I could reproduce the reported issue, but unfortunately what I mainly get are errors about slaptest and no logging of what is being done, so it's virtually impossible to do anything with this "test" suite.
Comment 18 Quanah Gibson-Mount 2020-08-04 22:37:11 UTC
Commits: 
  • 8849d83f 
by Howard Chu at 2020-08-04T22:04:14+00:00 
ITS#9279 fix Netscape password_expired control


  • e3875c18 
by Howard Chu at 2020-08-04T22:04:14+00:00 
ITS#9279 Netscape passwordExp controls came from draft-vchu-ldap-pwd-policy


  • 1a786469 
by Howard Chu at 2020-08-04T22:04:14+00:00 
ITS#9279 Handle Netscape controls in client tools


  • d4c7126e 
by Howard Chu at 2020-08-04T22:04:14+00:00 
ITS#9279 test Netscape password expiration controls

and do some LDIF cleanup
Comment 19 Quanah Gibson-Mount 2020-08-05 20:50:54 UTC
RE24:

Commits: 
  • 20a59e91 
by Howard Chu at 2020-08-04T23:26:43+00:00 
ITS#9279 fix Netscape password_expired control


  • 1e222584 
by Howard Chu at 2020-08-04T23:26:58+00:00 
ITS#9279 Netscape passwordExp controls came from draft-vchu-ldap-pwd-policy


  • 9ed30535 
by Howard Chu at 2020-08-05T16:20:02+00:00 
ITS#9279 Handle Netscape controls in client tools


  • 766cd03a 
by Howard Chu at 2020-08-05T19:50:40+00:00 
ITS#9279 test Netscape password expiration controls

and do some LDIF cleanup