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...