Subject: [ldapext] Various Password Policy Comments

From: "Andrew Sciberras" <[email-masked]>
Date: Thu, 20 Nov 2003 23:15:27 +1100

Hi!

Here are some concerns that I have about the password policy draft.
Many of these have been sent to some of the draft authors, but I don't
believe they ever made it to this mailing list.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 4.2.*
Shouldn't these operation attribute's have:

USAGE directoryOperation

aswell?

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 4.3.4, 4.3.5, 4.3.7.

Chances are low, but what do I do if the Expiration is Warned, I have
failures, or use grace logins multiple times within one generalizedTime
period?

It is illegal for me to store two values with the same value.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 4.3. Attribute Types for Password Policy State Information.

In this section the attributes pwdChangeTime, pwdAccountLockedTime,
pwdExpirationWarned, pwdReset and pwdPolicySubentry are all defined as being
SINGLE-VALUE.
Obviously this is correct, since there will only be one value for the state
attribute for each password attribute that the policy applies to.
However, we have chosen to implement our solution according to the
"Proposed Draft Amendments for Maximising Alignment between X.500 and LDAP"
(http://www.openldap.org/lists/ietf-ldapbis/200305/msg00024.html)

The SINGLE VALUE'dness of these attributes presents difficulties when
representing
these attributes in X.500. If the password policy applies to multiple
attributes,
our X.500 representation of the attribute will contain multiple values.
For this reason we have chosen not to include the SINGLE-VALUE
characteristic in
our implementation.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 4.3.1 - Password Policy State Attribute Option
"Since the password policy could apply to several attributes used to
 store passwords, each of the above operational attributes must have
 an option to specify which pwdAttribute is applies to."

Just a typo... "is" (third last word) should probably be "it".

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 4.3.2 - pwdAccountLockedTime
"A 0 value means that the account has been locked permanently,
 and that only an administrator can unlock the account."

It is unclear as to what a zero (0) value GeneralizedTime is. In our
implementation it has been assumed that this is the smallest legal
GeneralizedTime (00000101000Z).

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 5.2 Response Control.
The following is the ASN.1 of the Response Control as defined in the draft:
PasswordPolicyResponseValue ::= SEQUENCE {
      warning   [0] CHOICE OPTIONAL {
         timeBeforeExpiration  [0] INTEGER (0 .. maxInt),
         graceLoginsRemaining  [1] INTEGER (0 .. maxInt) }
      error     [1] ENUMERATED OPTIONAL {
         passwordExpired       (0),
         accountLocked         (1),
         changeAfterReset      (2),
         passwordModNotAllowed (3),
         mustSupplyOldPassword (4),
         invalidPasswordSyntax (5),
         passwordTooShort      (6),
         passwordTooYoung      (7),
         passwordInHistory     (8) } }

We have changed this to look like the one below.
The changes are adding a comma after the warning CHOICE, and putting the
OPTIONAL at the end of the braces.
PasswordPolicyResponseValue ::= SEQUENCE {
      warning   [0] CHOICE {
         timeBeforeExpiration  [0] INTEGER (0 .. maxInt),
         graceLoginsRemaining  [1] INTEGER (0 .. maxInt) } OPTIONAL,
      error     [1] ENUMERATED {
         passwordExpired       (0),
         accountLocked         (1),
         changeAfterReset      (2),
         passwordModNotAllowed (3),
         mustSupplyOldPassword (4),
         invalidPasswordSyntax (5),
         passwordTooShort      (6),
         passwordTooYoung      (7),
         passwordInHistory     (8) } OPTIONAL }

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 6.1.1 Bind Operation - Check for a locked account.
"If the value of the pwdAccountLockedTime attribute is 0, or if
 the current time is less than the value of the
 pwdAccountLockedTime attribute added to the value of the
 pwdLockoutDuration, the account is locked."

Once again, the value of zero (0) is assumed to be 0000010100Z.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Section 6.1.2D (Page 19)
>If the pwdExpirationWarned attribute is present and has a
>time value, the warning time is the value of the
>pwdExpirationWarned attribute plus the value of the
>pwdExpireWarning attribute minus the current time.

WarningTime = pwdExpirationWarned + pwdExpireWarning - Current Time

>If the pwdExpirationWarned attribute is not present, the
>server MUST subtract the current time from the time stored
>in pwdChangedTime to arrive at the password's age. If the
>age is greater than the value of the pwdMaxAge attribute
>minus the value of the pwdExpireWarning attribute, the
>server MUST set the current time as the value of the
>pwdExpirationWarned attribute, and the warning time is the
>value of pwdMaxAge minus the password's age.

PasswordAge = pwdChangeTime - CurrentTime
WarningTime = pwdMaxAge - PasswordAge

Firstly, I believe that the calculation of the PasswordAge is incorrect.
I think that the pwdChangeTime should be subtracted from the current time.

Following the warning time calculation steps described in the draft can also
lead to misleading results.
The example below will illustrate a scenario where this is the case.

pwdMaxAge = 100 seconds.
pwdExpireWarning = 50 seconds.
The user binds when the password is 80 seconds old.
PasswordAge = 80.
WarningTime = (pwdMaxAge - PasswordAge) = 20 seconds.
At this stage the user has been told that their password will expire in 20
seconds.

User binds again in 5 seconds time. (I.e. PasswordAge = 85 seconds).
Since the pwdExpirationWarned is now present we calculate the warning time
differently.

WarningTime = (pwdExpirationWarned + pwdExpireWarning - CurrentTime)
  = (pwdExpirationWarned - CurrentTime) + pwdExpireWarning
  = (-5) + 50
  = 45
The user is now told that their password will expire in 45 seconds.
Our implementation of the password policy will simply return
pwdExpireWarning as the first warning time value.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Section 6.1.2B (Page 20)
>If the number of these failures is greater or equal to the
>pwdMaxFailure attribute, the server MUST lock the account
>by setting the value of the pwdAccountLockedTime attribute
>to the current time. After locking the account, the server
>MUST send a bindResponse to the client with the
>resultCode: unwillingToPerform (53), and MUST include the
>passwordPolicyResponse in the controls field of the
>bindResponse message with the error: accountLocked (1).

I do not think that the return code should be unwillingToPerform. In this
scenario, the user has got their password wrong and this incorrect attempt
has made the number of failures exceed the pwdMaxFailure limit. In this case
the reason why the operation (BIND) is going to fail is because of the
incorrect password. The fact that the number of bind failures has exceeded a
policy limit is just a consequence of that.
For this reason I believe that the resultCode should be invalidCredentials.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 6.2.(1&2) Modify Password Operation.
Just a personal opinion, I think that the pwdMustChange setting should take
precedence over the pwdSafeModify one. I therefore think that it would
probably make more sense to swap steps one and two around. From an
implementation point of view I also feel that it is easier and quicker to
make the pwdMustChange check over the pwdSafeModify one. This will result in
the DSA performing less operations to determine that the user has broken a
policy rule.

I also think that it should be stated that if the password is being modified
by an administrator the pwdSafeModify policy rule should be ignored.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 6.2.9
The pwdReset attribute should not be removed if an Administrator has
modified the Password value.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 6.3.2B
>If the server is unable to check the length (due to a hashed
>password or otherwise), the value of pwdCheckSyntax MUST be
>evaluated. If the value is 1, operation MUST continue. If the
>value is 2, the server MUST send an addResponse to the client
>with the resultCode: constraintViolation (19), and MUST
>include the passwordPolicyResponse in the controls field of
>the addResponse message with the error: passwordTooShort (5).

A passwordTooShort error code here seems inappropriate. Since the server
could not determine the length due to the syntax of the password wouldn't it
be more appropriate to use a invalidPasswordSyntax error code.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Section 6.3.3
After this step there should be a step number 4. It should state that the
pwdReset attribute MUST be set to true.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 6.4.2A
Since we have had a successful compare, I believe that the
pwdAccountLockedTime should be removed at this stage as well.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Section 6.4.2C
I believe that the Warning Time calculations here should be amended to my
recommendations of section 6.1.2D.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

*Section 6.4.2D
>If the result of the compare operation is false, the server MUST
>do the following:
 <snip>
>D. If no errors were returned, the server MUST send a
>compareResponse with the resultCode: compareTrue (6), and
>MUST include the passwordPolicyResponse with nothing in
>the SEQUENCE.
Section D above is related to the fact that the compare was false. The
server should therefore return compareFalse.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 7.5 Other Operations
>For operations other than bind, unbind, abandon, search or StartTLS,
>the client MUST check the following result code and control to
>determine if the user needs to change the password immediately.

I don't think that a search operation should be permitted if the user must
change their password now.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*Section 8 - Administration of a Password Policy
I think a value for the administrativeRole operational attribute
(as defined in
http://www.ietf.org/internet-drafts/draft-zeilenga-ldap-subentry-07.txt)
should be specified for the password policy subentry.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Just a note for developers of X.500/LDAP directories which come from an
X.500 background:
A portion of the pwdHistory value contains the string representation of the
dotted-decimal
OID that defines the syntax used to store the password.
Not all X.500 syntax's have an LDAP specific encoding or a syntax OID, which
make pwdHistory
maintenance impossible.

Cheers,
Andrew Sciberras
Adacel Technologies

P.S.
Jim, thanks for providing me with these concerns after I had lost them.

_______________________________________________
Ldapext mailing list
[email-masked]
https://www1.ietf.org/mailman/listinfo/ldapext