4

I have an interesting problem, I am writing a password management webpage/service and I am trying to find a way to determine when a user's password is going to expire so I can manually reset their other passwords with it and send out an email, etc.

The problem I'm having is that when trying to loop through my users I'm getting the bulk of them not having a pwdlastset attribute so I can't determine when it's going to expire.

So I guess I am looking for ideas on a good way to check for when a user's password is going to expire aside from using the pwdlastset property and calculating the time left.

Thanks a bunch.

Jimmy
  • 9,686
  • 14
  • 59
  • 78

3 Answers3

8

It's actually quite a bit more complicated than you might think at first...

  • in order to know how long a password can be valid, you need to read a "domain policy" and find out that way

Then:

  • if the user has the "UF_DONT_EXPIRE_PASSWD" flag set in his "userAccountControl", his password will never expire
  • if the "pwdLastSet" value (a "ADSLargeInteger" or Int64 value, which is rather tricky to read in the first place) is 0, the user will have to change his password the next time he logs on
  • if the "pwdLastSet" value is -1, the password has never been set
  • only if none of the above are true, then the "pwdLastSet" value contains the date when the password was last set, to which you can add the "MaxPasswordAge" from the domain policy, and this will give you the date when the user's password is going to expire

Phew! Did you think it would be this tricky? :-)

Marc

PS: If you're serious about .NET based AD programming, you ought to have this book:

DevGuide

The .NET Developer's Guide to Directory Services Programming

The book contains all the goodies like determining user's password expiration dates, determining user account lockout state and much much more - highly recommended! Joe and Ryan did an outstanding job getting all this information together and explaining it so that even an average Joe programmer like myself can understand it :-)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
  • it seems the user running my AD queries didn't have permission to view the properties of everyone, so now it seems like I can view the pwdlastset attribute, now a new problem arises with accounts that are technically disabled but not indicated as such in the useraccountcontrol, is there another setting where it would be viewable? – Jimmy Sep 01 '09 at 17:09
  • phew! You hit all the hard ones, eh? Determining account lockout is another odyssey on its own.... unfortunately, the UF_LOCKOUT flag on UserAccountControl isn't really used for that :-( – marc_s Sep 01 '09 at 17:14
  • @JImmy: get the book I mentioned - it contains all the answers, and a lot more :-) Good stuff indeed – marc_s Sep 01 '09 at 17:17
  • 1
    Thanks for the link, probably going to order that, and also thanks for your help, this has been an endeavor – Jimmy Sep 01 '09 at 17:57
  • hi @Jimmy i also have the same situation. how did you solve this problem? :) – Vincent Dagpin Oct 29 '14 at 03:21
0

As far as I know, if pwdlastset is zero or missing, the user is either required to change their password at the next logon or their account is setup with a non-expiring password. Could this be the cause of what you are seeing?

Jeff Siver
  • 7,434
  • 30
  • 32
0

Here's another approach:

public static DateTime GetPasswordExpirationDate(UserPrincipal user)
{
    DirectoryEntry deUser = (DirectoryEntry)user.GetUnderlyingObject();
    ActiveDs.IADsUser nativeDeUser = (ActiveDs.IADsUser)deUser.NativeObject;
    return nativeDeUser.PasswordExpirationDate;
}

You'll need to add a reference to the ActiveDS COM library typically found at C:\Windows\System32\activeds.tlb.

Tawab Wakil
  • 1,737
  • 18
  • 33