Full_Name: Andrew Thorburn Version: 2.4.35 OS: N/A URL: Submission from: (NULL) (203.97.178.157) The problem is very simple: According to the Behera Password Policy Draft (http://tools.ietf.org/html/draft-behera-ldap-password-policy-10), the attribute graceAuthNsRemaining should be set to the number of grace authentications remaining. However, with the following policy extract: pwdMaxAge: 1 pwdMustChange: TRUE pwdAllowUserChange: TRUE pwdSafeModify: TRUE pwdGraceAuthNLimit: 2 Running ldapwhoami results in the following: ldap_bind: Success (0) (Password expired, 2 grace logins remain) dn:uid=ANDREWT,ou=People,dc=example,dc=com That is not correct - there is only a single grace login remaining. I have used up one of the two grace logins provided by binding to OpenLDAP to execute the ldapwhoami command. Executing the same command twice more results in the following: $ ldapwhoami -h remotehost -e ppolicy -D uid=ANDREWT,ou=People,dc=example,dc=com -w andrew10 ldap_bind: Success (0) (Password expired, 1 grace logins remain) dn:uid=ANDREWT,ou=People,dc=example,dc=com $ ldapwhoami -h remotehost -e ppolicy -D uid=ANDREWT,ou=People,dc=example,dc=com -w andrew10 ldap_bind: Invalid credentials (49); Password expired Whereas I would have assumed, both from the message returned and from the language in the draft, that the first invocation would have said "(Password expired, 1 grace logins remain)", followed by then denying access for the next two invocations. Well, actually, what I would *expect* to happen is the first would return "1 remains", the second "0 remain" and the third would deny access, but the draft policy is pretty explicit, IMO, that the former is what should happen (which is daft). Now, according to the spec: "If there are remaining grace authentications as per Section 7.4, the server adds a new value with the current time in pwdGraceUseTime. Then it sends to the client a response with an appropriate successful resultCode (i.e. success (0), compareTrue (6), etc.), and includes the passwordPolicyResponse in the controls field of the response message with the warning: graceAuthNsRemaining choice set to the number of grace authentications left." This suggests, at least to me, that a new value should be added to pwdGraceUseTime *before* calculating the number of remaining grace logins. Admittedly, that wouldn't actually fix the issue, as it would result in the final grace login failing. Oops. This looks a lot like a bug to me, but at the same time, it also seems to be trying to adhere to the letter of the policy while also doing what is expected (e.g. if pwdGraceAuthNLimit is 1, I should be able to login once, while according to the letter of the policy pwdGraceAuthNLimit: 1 == pwdGraceAuthNLimit: 0...) The simplest fix, at least that I can see, would be to add the statement "ngut--;" at some point after the statement if (ngut < 1) { ppb->pErr = PP_passwordExpired; rs->sr_err = LDAP_INVALID_CREDENTIALS; goto done; } e.g. if (ngut < 1) { ppb->pErr = PP_passwordExpired; rs->sr_err = LDAP_INVALID_CREDENTIALS; goto done; } ngut--; Or perhaps after we've created the grace user time attribute modification. This would be done to account for the fact that we are, right now, using up a single one of the pwdGraceUseTime values, and that once we're done, ngut should indeed be one less than it currently is - there will be (ngut - 1) grace logins *remaining* after this method invocation finishes. This may seem like a really small thing, but it's causing problems for me...
Tested my idea about patching it, and it didn't work. There's something, somewhere, that doesn't like values of 0, and so doesn't include the graceAuthN warning in the returned password control if ngut is 0. I still believe what I have described above is an error, but I don't know enough about C or the internal structure of OpenLDAP to figure out why it's not working, and how (or even if) it can be fixed.
I'm not 100% sure that's the wrong number to return (according to the spec) as we should return "the number of values in that attribute subtracted from the value of pwdGraceAuthNLimit" and the number of values is one lower that you would expect while we're still processing the bind. Might be worth changing the message in the client to reflect that?
Commits: • d1799a50 by Ondřej Kuzník at 2021-02-24T17:03:22+00:00 ITS#7596 Report correct number of grace authentications left