Link to home
Start Free TrialLog in
Avatar of MsFox
MsFox

asked on

Get the passwordlastchanged property in active directory

Hi,

I really really need an urgent reply so I decided to put this in a separate thread.

How do you search for a user in the active directory tree starting from the root and get the passwordlastchanged property of the user.

Is it possible to search for a user and get the passwordlastchanged property if you only know the domain name?

Thanks for your patience.
Avatar of ihenry
ihenry


PasswordLastChanged is a property member of IADsUser ADSI interface from a COM dll. To use it you need to make an interop assembly from the COM dll. I have a better alternative for you, get pwdLastset attribute from a user object and convert its value to a datetime value.

Take a look at the following PAQ, it has working code to search a user given his user domain id.
https://www.experts-exchange.com/questions/21319791/Get-ActiveDirectory-department-of-connected-user-using-ASP-NET-C.html

With a small modification you can easily get the pwdLastset attribute value, like so

long pwdLastset = 0L;
if ( sr.Properties.Contains("pwdLastset") )
{
      pwdLastset = (long) sr.Properties["pwdLastset"][0];
      if (pwdLastset > 0)
      {
      DateTime pwdLastChanged = DateTime.FromFileTime( pwdLastSet );
      }
}

Not in all cases pwdLastset returns a non zero value. For more detail info, read this PAQ.
https://www.experts-exchange.com/questions/21038518/Detect-expired-Active-Directry-user-passwords-and-change-via-ASP-NET.html
Avatar of MsFox

ASKER

Ok, I am able to get the pwdLastset.   Thanks for that.

Now I'm getting constraint violation.  Do you have any idea what causes this?

Thanks again.
Can you post the code in where the exception gets thrown?
Avatar of MsFox

ASKER

I got it during the actual  changing of password. In my screen, I've got 3 textboxes for the old password, new password and confirm new password.  When the user clicks save button, below is the code for the click event.


rootDSE = New DirectoryEntry(String.Format("LDAP://{0}/rootDSE", dcDNS), userName, oldPassword, _
            AuthenticationTypes.Secure)

            rootDN = DirectCast(rootDSE.Properties("defaultNamingContext").Value, String)

            searchRoot = New DirectoryEntry(String.Format("LDAP://{0}/{1}", dcDNS, rootDN), userName, oldPassword, _
            AuthenticationTypes.Secure)

            searcher = New DirectorySearcher(searchRoot)

            searcher.Filter = String.Format("sAMAccountName={0}", userName)

            searcher.SearchScope = SearchScope.Subtree

            searcher.CacheResults = False

            results = searcher.FindAll

            For Each result In results

                userEntry = result.GetDirectoryEntry

                Exit For

            Next result



            If userEntry Is Nothing Then

                Throw New InvalidOperationException("User not found in the domain")

            End If

            userEntry.Invoke("ChangePassword", New Object() {oldPassword, newPassword})

            userEntry.CommitChanges()

            ChangePassword = True

        Catch tie As System.Reflection.TargetInvocationException

            Throw tie.InnerException

        Catch ce As System.Runtime.InteropServices.COMException

            Throw ce

        Finally

            If Not userEntry Is Nothing Then userEntry.Dispose()

            If Not results Is Nothing Then results.Dispose()

            If Not searcher Is Nothing Then searcher.Dispose()

            If Not searchRoot Is Nothing Then searchRoot.Dispose()

            If Not rootDSE Is Nothing Then rootDSE.Dispose()

        End Try

---
Thanks for any help.
Can you post the exception stack trace too?
Avatar of MsFox

ASKER

Here it is:

A constraint violation occurred.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Runtime.InteropServices.COMException: A constraint violation occurred.

Source Error:


Line 173:        Catch tie As System.Reflection.TargetInvocationException
Line 174:
Line 175:            Throw tie.InnerException
Line 176:
Line 177:        Catch ce As System.Runtime.InteropServices.COMException
 

Source File: C:\Inetpub\wwwroot\Client Connect\Version 3\BL_Security\ClientConnect.vb    Line: 175

Stack Trace:


[COMException (0x8007202f): A constraint violation occurred.]
   BL_Security.ClientConnect.ChangePassword(String userName, String oldPassword, String newPassword) in C:\Inetpub\wwwroot\Client Connect\Version 3\BL_Security\ClientConnect.vb:175
   ClientConnectv3.ChangePassword.cmdSave_Click(Object sender, EventArgs e) in C:\Inetpub\wwwroot\ClientConnectv3\Pages\ChangePassword.aspx.vb:63
   System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
   System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +57
   System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
   System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
   System.Web.UI.Page.ProcessRequestMain() +1277

 

Sounds like something is wrong with the password. Are you using a password which meets your domain password policy?
Avatar of MsFox

ASKER

Yeah, you're right.  I am violating our domain password policy.  

I've one more related question.  Hope I'm not asking too much.

I am able to get the pwdlastSet of any user by just knowing the domain name and the username.  But users belongs to different OUs.  We have external and internal OUs.  How can I determine if the user in question belongs to external or internal OUs?

Thanks heaps.
ASKER CERTIFIED SOLUTION
Avatar of ihenry
ihenry

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of MsFox

ASKER

Thanks henry