Recently a post on ActiveDir org reminded me that with even as much as I know about Active Directory, I still have more to learn and likely always will have more to learn. The information I put forth in this blog post may be well known to some of the folks who read it but I know there are many who didn’t have a clue or just recently learned it while I learned it publicly on ActiveDir Org and the related testing I performed during the posting myself.
The basic question was around Password Settings Objects (PSO’s) and specifically around msDS-LockoutDuration and msDS-LockoutObservationWindow. These attributes are used to define various parts of the lockout policy, specifically
- msDS-LockoutDuration specifies how long an ID is locked out, once locked.
- msDS-LockoutObservationWindow specifies how long the system should collect bad password attempts to compare to the msDS-LockoutThreshold value. For example, say your threshold is specified as 10 and you get 5 bad attempts an hour with no good attempts between the bad attempts. If your observation window is 60 minutes, you won’t ever lock out because it is only seeing 5 bads during that period. If you set the observation window to 120 minutes, well now you will get 10 bad attempts in the period and the account will lock. Make sense? Note that this DOES NOT reset the badPwdCount attribute.
The question was about what was documented in technet, specifically “The value of msDS-LockoutObservationWindow cannot be smaller than the value of msDS-LockoutDuration.” found in Appendix B: PSO Attribute Constraints (http://technet.microsoft.com/en-us/library/cc753858(WS.10).aspx).
It seems the original poster (OP) was running into an issue with setting his desired lockout policy. Specifically he wanted to set the following
Account Lockout Duration |
0 |
Account Lockout Threshold |
4 |
Reset Account Lockout Counter After |
1 day |
and was attempting to create the PSO via LDIF (which is fully supported) with the following
dn:CN=PSO_AdminUser,CN=Password Settings Container,CN=System,dc=intra,dc=contoso,dc=com
changetype:add
objectClass:msDS-PasswordSettings
msDS-MaximumPasswordAge:-25920000000000
msDS-MinimumPasswordAge:-864000000000
msDS-MinimumPasswordLength:10
msDS-PasswordHistoryLength:24
msDS-PasswordComplexityEnabled:TRUE
msDS-PasswordReversibleEncryptionEnabled:FALSE
msDS-LockoutObservationWindow:-864000000000
msDS-LockoutDuration:0
msDS-LockoutThreshold:10
msDS-PasswordSettingsPrecedence:30
msDS-PSOAppliesTo: CN=DL_ADDS_AdminPWpolicy,ou=groups,ou=_shared,ou=_justice,dc=intra,dc=contoso,dc=com
And when he specifies an account lockout duration of 0, he means the popularly well known/understood value that we see in the domain policy when you specify 0 which is to mean “require administrator to unlock” as seen in the following image.
When he ran the LDIF file through LDIFDE, Active Directory unexpectedly (to many of us) kicked back an error. Specifically “Unwilling To Perform” or more specifically “Extended Error: 000020E7: SvcErr: DSID-030F03B5, problem 5003 (WILL_NOT_PERFORM), data 0” which is duplicated with AdFind for your enjoyment here:
C:\temp>admod -b "CN=newpso10,CN=Password Settings Container,CN=System,DC=k8dom,DC=loc" msDS-LockoutDuration::0 msds-LockoutObservationWindow::-864000000000 -exterr
AdMod V01.12.00cpp Joe Richards (joe@joeware.net) February 2010
DN Count: 1
Using server: k8dom-dc1.k8dom.loc:389
Directory: Windows Server 2008Modifying specified objects…
DN: CN=newpso10,CN=Password Settings Container,CN=System,DC=k8dom,DC=loc…: [k8dom-dc1.k8dom.loc] Error 0x35 (53) – Unwilling To PerformExtended Error: 000020E7: SvcErr: DSID-030F03B5, problem 5003 (WILL_NOT_PERFORM), data 0
ERROR: Too many errors encountered, terminating…
The command did not complete successfully
I was a bit shocked by this as I, like everyone else, has been taught by years and years of Windows experience that infinite lockout is a 0 value for duration but it didn’t work when you specified it in the PSO. I looked at the source code for PSO validation and it definitely showed that this error should be thrown based on that input. I, again, so well indoctrinated about what 0 means for lockout thought, wow, this is a bug and forwarded to a friend in the DS team. My friend didn’t see a flaw in my logic or at least didn’t point one out and my relationship with the DS guys is generally pretty open and if I am being stupid, they don’t have an issue telling me. :) Anyway he indicated he would look into it.
In the meanwhile, my recommendation to the OP as a workaround was just to set the lockout duration to some large value such as one year as that would effectively be an unlimited lockout. If someone locks an account and then sits around waiting for a year to try to attack it again… all the power in the world to them… If they are that patient then likely any value for observation window likely isn’t going to work for you since they are patient enough to wait for it to reset before trying again. Certainly waiting 10 minutes or a day or 20 days is less than waiting a year. The OP seemed content with this and I figured I would just hear back from MSFT eventually saying it was “fixed”.
A bit later, the OP came back with another post indicating that one of his friends pointed out a TechNet article (http://technet.microsoft.com/en-us/library/cc754461(WS.10).aspx) that indicated that you could specify the value of “(never)” in ADSIEDIT when working on PSO’s, and in fact he had tried it and indeed it seemed to work. This was interesting to me since the attribute is of type 2.5.5.16 (aka LARGEINTEGER) and obviously “(never)” is not a LARGEINTEGER. I fired up ADSIEDIT and tested setting msDS-LockoutDuration to (never) and as specified by the OP, shockingly, it did in fact work.
At that point all sorts of theories popped into my head but the first thing I needed to do was test to see if “(never)” was being handled by ADSIEDIT or the DSA. This is an easy test:
C:\temp>admod -b "CN=newpso10,CN=Password Settings Container,CN=System,DC=k8dom,DC=loc" msDS-LockoutDuration::(never) -exterr
AdMod V01.12.00cpp Joe Richards (joe@joeware.net) February 2010
DN Count: 1
Using server: k8dom-dc1.k8dom.loc:389
Directory: Windows Server 2008Modifying specified objects…
DN: CN=newpso10,CN=Password Settings Container,CN=System,DC=k8dom,DC=loc…: [k8dom-dc1.k8dom.loc] Error 0x15 (21) – Invalid SyntaxExtended Error: 00000057: LdapErr: DSID-0C090B73, comment: Error in attribute conversion operation, data 0, v1771
ERROR: Too many errors encountered, terminating…
The command did not complete successfully
This authoritatively proved the “(never)” value was being handled in ADSIEDIT. So looking at the PSO object after ADSIEDIT set the attribute to the value –9223372036854775808.
C:\temp>adfind -b "CN=newpso10,CN=Password Settings Container,CN=System,DC=k8dom,DC=loc" -samdc -tdcd -tdcas msds-lockoutduration
AdFind V01.41.00cpp Joe Richards (joe@joeware.net) February 2010
Using server: k8dom-dc1.k8dom.loc:389
Directory: Windows Server 2008dn:CN=newpso10,CN=Password Settings Container,CN=System,DC=k8dom,DC=loc
>msDS-LockoutDuration: -9223372036854775808 [undefined]1 Objects returned
This was all previously unknown to me but made sense, and in fact, the workaround I mentioned to the OP was drifting in this direction. However… this made me think… what about the domain policy? Does the same thing happen there? You set the domain policy (normally) via the Group Policy Editor tools, editing it via LDAP never really comes up[1]. So to validate I edited the domain policy to unlimited duration lockout and checked the lockoutDuration attribute on the domain head and sure enough, it had the same value.
C:\temp>adfind -default -s base lockoutduration
AdFind V01.41.00cpp Joe Richards (joe@joeware.net) February 2010
Using server: k8dom-dc1.k8dom.loc:389
Directory: Windows Server 2008
Base DN: DC=k8dom,DC=locdn:DC=k8dom,DC=loc
>lockoutDuration: -92233720368547758081 Objects returned
Shortly after working this out, my DS team friend got back to me and indicated that the PSO value checking was pulled straight from the domain value checking and it was likely something handled in the GUI. That of course aligned exactly to what I was seeing and explained what I figured out. I also said the documentation all needs to be updated to reflect this information. It wasn’t so important when just the domain policy was involved because the primary supported mechanism for updating the domain policy is through the GPO Editor, but PSO’s bring a new twist to this and using LDAP tools like LDIFDE are indicated to create and manage these objects.
Hopefully folks find this info useful and now I have to add a DCR to the list of DCRs for PSOMgr, AdMod and AdFind to reflect this new information.
joe
[1] An unlimited lockout duration also doesn’t normally come up for me. It isn’t something I recommend as lockouts can be used for some nasty Denial Of Service (DOS) attacks.