Resetting an Active Directory accounts' password...

Rate It (2)

Last post 03-27-2008 1:16 PM by walalm. 74 replies.

Sort Posts:

  • Resetting an Active Directory accounts' password...

    08-22-2003, 7:20 AM
    • Loading...
    • Denvas
    • Joined on 04-05-2003, 7:58 PM
    • Posts 50
    Hi,

    I'm trying to reset a password in Active Directory on a Windows 2000 Advanced Server. It's not really working with the code I have. Any ideas on how do this utilizing the ASP.NET Framework 1.1 (in VB.NET please). ANY help is much appreciated.

    Thanks,
    Denvas
            'create the pathname
    
    Pathname = "WinNT://server.domain.com/NetID,user"

    'Reset the password
    Try
    'Create the object
    Usr = GetObject(Pathname)

    Usr.SetPassword(LCase(NetID))
    Usr.AccountDisabled = False
    Usr.SetInfo()

    Usr.Put("PasswordExpired", CLng(1)) ' User must change password at next logon.
    Usr.SetInfo()
  • Re: Resetting an Active Directory accounts' password...

    08-22-2003, 8:19 AM
    • Loading...
    • dunnry
    • Joined on 06-24-2002, 12:17 PM
    • http://directoryprogramming.net
    • Posts 1,806
    • TrustedFriends-MVPs
    What is the error you are getting? The code you are using is native ADSI, while the equivalent code would use System.DirectoryServices in .NET.

    EDIT - This post has a good conversation here about SetPassword and its issues (especially with Windows 2000).  After learning more about security and what the TCB privilege entails, I can no longer recommend giving the ASPNET account this privilege ("Act as part of the operating system").  Everywhere below where you see that, keep this in mind.  Instead, for Windows 2003 and XP, it is no longer an issue, but for Windows 2000, I would recommend pulling code out of process into COM+ or working around the TCB limitation by using Keith Brown's SSPI technique to obtain the user's token outside the TCB for impersonation.

    I cannot update all the parts in here, but please keep this in mind.
  • Re: Resetting an Active Directory accounts' password...

    08-22-2003, 12:15 PM
    • Loading...
    • Denvas
    • Joined on 04-05-2003, 7:58 PM
    • Posts 50
    I'm not actually getting an error - it's simply not resetting.

    I'm taking that code from a regular ASP page that was created previously. Unfortunately, it doesn't seem to work. Would you know how to reformat that for .NET? I'm just not sure of the syntax. I do know that I need to use the System.DirectoryServices, just don't know much more after that. I've tried looking for the answer - but I can't find it.

    Thanks
  • Re: Resetting an Active Directory accounts' password...

    08-22-2003, 12:38 PM
    • Loading...
    • dunnry
    • Joined on 06-24-2002, 12:17 PM
    • http://directoryprogramming.net
    • Posts 1,806
    • TrustedFriends-MVPs
    It should throw an error if it doesn't reset it properly. What is your catch statement doing? Are you discarding the error? I am not a VB coder, so you might need a translation service for this, but it should be almost identical:
    Pathname = "WinNT://server.domain.com/NetID,user"
    

    'Reset the password
    Try
    'Create the object
    Usr = GetObject(Pathname)

    Usr.SetPassword(LCase(NetID))
    Usr.AccountDisabled = False
    Usr.SetInfo()

    Usr.Put("PasswordExpired", CLng(1)) ' User must change password at next logon.
    Usr.SetInfo()
    Would be something like this:

    const int ADS_UF_ACCOUNTDISABLE = 0x0002;

    string pathname = "WinNT://server.domain.com/NetID,user";

    DirectoryEntry user = new DirectoryEntry(pathname);
    //Optionally provide credentials to connect to SAM
    //user.Username = "DOMAIN\\User";
    //user.Password = "password";
    user.AuthenticationTypes = AuthenticationTypes.Secure;

    //Reset Password
    user.Invoke("SetPassword", new object[]{"newpassword"});

    //Enable account
    int flags = user.Properties["userAccountControl"].Value;
    user.Properties["userAccountControl"].Value = flags & ~ADS_UF_ACCOUNTDISABLE;
    user.CommitChanges();

    //Change Password at next logon
    user.Properties["passwordExpired"][0] = 1;
    user.CommitChanges();
    Check MSDN's website for more VB.NET snippets of code to do common tasks: VB.NET Snippets

    Note that C# has more examples on the site, so you might need to convert them.
  • Re: Resetting an Active Directory accounts' password...

    08-22-2003, 10:32 PM
    • Loading...
    • Denvas
    • Joined on 04-05-2003, 7:58 PM
    • Posts 50
    Thank you so much for your help. I'm going to try it out first thing Monday morning. Someone did refer me to a translator - so this is very helpful.

    Have a great weekend.

    Denvas
  • Re: Resetting an Active Directory accounts' password...

    08-25-2003, 10:40 AM
    • Loading...
    • Denvas
    • Joined on 04-05-2003, 7:58 PM
    • Posts 50
    Hello,

    I tried this code and I'm having the same problem - It's not resetting, and not giving any errors. So I'm assuming the code is OK, maybe something with Active Directory? Is there something that needs to be set? I know they've been working with Active Directory here at my job - but I'm not sure what they may have changed. It resets the passwords perfectly in the 'Active Directory Users and Computers' interface. I bring this up to those involved, and they say it's working perfectly - since their not developers, I'm at a loss.

    Any ideas?
  • Re: Resetting an Active Directory accounts' password...

    08-25-2003, 12:00 PM
    • Loading...
    • dunnry
    • Joined on 06-24-2002, 12:17 PM
    • http://directoryprogramming.net
    • Posts 1,806
    • TrustedFriends-MVPs
    Can you post the code you are using now and any try/catch statements you have surrounding it?
  • Re: Resetting an Active Directory accounts' password...

    08-26-2003, 7:46 AM
    • Loading...
    • Denvas
    • Joined on 04-05-2003, 7:58 PM
    • Posts 50
    Thanks for your interest in helping me out - it is so appreciated.

    Here's the VB.NET version of the code you gave me. I finally am getting an error (I was putting the 'Successful' message within the finally statement.) It's telling me the user cannot be found - when I KNOW that the username is 100% correct. I've even tested on my own account with the same results.

    - Denvas

    Here's the code:
    'create the pathname
    Pathname = "WinNT://Server.Domain.com/" & NetID & ",user"

    'Reset the password
    Try
    Const ADS_UF_ACCOUNTDISABLE As Integer = &H2

    Dim user As New DirectoryEntry(Pathname)

    user.AuthenticationType = AuthenticationTypes.Secure

    'Reset Password
    user.Invoke("SetPassword", NetID) 'THIS IS WHERE THE ERROR OCCURS

    'Enable account
    Dim flags As Integer = user.Properties("userAccountControl").Value

    user.Properties("userAccountControl").Value = flags And Not ADS_UF_ACCOUNTDISABLE

    user.CommitChanges()

    'Change Password at next logon
    user.Properties("passwordExpired").Item(0) = 1

    user.CommitChanges()

    Catch ex As Exception
    Message.Text = "Error Resetting password for " & NetID & ": " & ex.Message
    Exit Sub
    End Try

    Message.Text = "Password reset successfully for " & NetID
  • Re: Resetting an Active Directory accounts' password...

    08-26-2003, 9:54 AM
    • Loading...
    • Denvas
    • Joined on 04-05-2003, 7:58 PM
    • Posts 50
    Sorry, I actually found the problem. The prior DBA, had set SQL SERVER fields to CHAR and not VarChar, adding many spaces - of course not finding it in AD. Now, it's giving me an Access is Denied error, but that I could probably deal with the Network Admins.

    Thanks again for all your help,
    Denvas
  • Re: Resetting an Active Directory accounts' password...

    08-26-2003, 10:10 AM
    • Loading...
    • dunnry
    • Joined on 06-24-2002, 12:17 PM
    • http://directoryprogramming.net
    • Posts 1,806
    • TrustedFriends-MVPs
    That's good you know what is happening now. If you need more help, post back. One item to think about is to use the LDAP:// provider instead of the WinNT:// provider. If you are using AD, then it is probably a better solution to use the LDAP:// provider since it has a bit more functionality than the older WinNT:// provider, which is really just there for compatibility.
  • Re: Resetting an Active Directory accounts' password...

    08-26-2003, 10:50 AM
    • Loading...
    • Denvas
    • Joined on 04-05-2003, 7:58 PM
    • Posts 50
    I was actually looking at that (LDAP). I'll definitely do that.

    I asked the Net. Admins. here and it seems 'Everyone' has the right to change their own passwords. But that invoke method still creates an access denied error.
    I changed the authentication type to : user.AuthenticationType = AuthenticationTypes.Secure, because all users within the organization are authenticated with their logins (Integrated Windows Authentication).
    The instructions say that a flag has to be used as well when using this type. OK, but unfortunately, M.S. doesn't say how to do this or what to set it to.

    Heck, I'm not even sure if this is even the problem.

    Could this be linked to the LDAP syntax you mentioned?

    Thanx,
    Denvas
  • Re: Resetting an Active Directory accounts' password...

    08-26-2003, 11:08 AM
    • Loading...
    • Denvas
    • Joined on 04-05-2003, 7:58 PM
    • Posts 50
    OK, now that I'm being a real pain...

    I changed the code for the LDAP - I probably made it harder than it needs to be. But not only am I new to VB.NET, I'm also new to AD - so not really sure how to create the proper syntax. So this is what I did, and am now getting a different error ("Exception has been thrown by the target of an invocation") - If it's not one thing it's another, huh?:

    Try
    Const ADS_UF_ACCOUNTDISABLE As Integer = &H2

    Dim user As New DirectoryEntry() '(Pathname)
    Dim entry As New DirectoryServices.DirectoryEntry("LDAP://Domain.com")
    Dim Serchr As New System.DirectoryServices.DirectorySearcher(entry)

    Serchr.Filter = ("(samAccountName=" & NetID & ")")

    user = New DirectoryEntry(Serchr.FindOne.GetDirectoryEntry.Path)

    user.AuthenticationType = AuthenticationTypes.Secure

    'Reset Password
    user.Invoke("SetPassword", NetID) 'THIS IS WHERE THE ERROR OCCURS

    'Enable account
    Dim flags As Integer = user.Properties("userAccountControl").Value

    user.Properties("userAccountControl").Value = flags And Not ADS_UF_ACCOUNTDISABLE

    user.CommitChanges()

    'Change Password at next logon
    user.Properties("passwordExpired").Item(0) = 1

    user.CommitChanges()

    Catch ex As Exception
    Message.Text = "Error Resetting password for " & NetID & ": " & ex.Message & ex.StackTrace
    Exit Sub
    End Try
  • Re: Resetting an Active Directory accounts' password...

    08-26-2003, 11:20 AM
    • Loading...
    • dunnry
    • Joined on 06-24-2002, 12:17 PM
    • http://directoryprogramming.net
    • Posts 1,806
    • TrustedFriends-MVPs
    Oh, I see what is happening now. Only Admin's are allowed to use 'SetPassword' functionality. I assumed you were running this code as an admin. If user are running this themselves, they need to use 'ChangePassword' function instead. 'SetPassword' ignores any password policy on the domain and doesn't require the user's previous password. 'ChangePassword' observes both.

    To use it:
    user.Invoke("ChangePassword", new object[]{"oldpass", "newpass"});
    The AuthenticationTypes.Secure flag should be used as well as you have it.
  • Re: Resetting an Active Directory accounts' password...

    08-26-2003, 1:29 PM
    • Loading...
    • Denvas
    • Joined on 04-05-2003, 7:58 PM
    • Posts 50
    I tried the "ChangePassword" way and it's still giving me an "Access Denied" error.

    I should've explained what I'm trying to do from the beginning. At my job, we have about 3000 users, and they're always having problems where their passwords need to be reset. Administration doesn't want just anybody to go into the Active directory interface - so they asked me to create an ASP.NET page that allows anybody in our IT department (about 140 people) to reset any of those 3000 peoples' passwords (WITHOUT knowing the original password). So it's limited access to Active Directory.

    Now, the ChangePassword is somewhat working. I used it on myself, and it does change the password, but then triggers an error: "Exception has been thrown by the target of an invocation." right at the Invoke statement - "user.Invoke("ChangePassword", "olPwd", "newPwd"). But it still gives me "Access Denied" when I try to change/reset another accounts' password. Again, I need this to change the password to the new default password without knowing the original - and it could be done by anybody.

    Are there any good resources I could look up? Nothing on the net seems detailed enough.

    'The AuthenticationTypes.Secure flag should be used as well as you have it.' means just leave it the way it is, right?

    It feels like the problem is almost solved.

    Thanks,
    Denvas
  • Re: Resetting an Active Directory accounts' password...

    08-26-2003, 2:43 PM
    • Loading...
    • dunnry
    • Joined on 06-24-2002, 12:17 PM
    • http://directoryprogramming.net
    • Posts 1,806
    • TrustedFriends-MVPs
    If you are having people set the password for others, then you will definitely need to use SetPassword. I was thinking you were talking about self-service. Ok, so SetPassword tries to reset the password in Windows 2000 in 3 ways:

    1.) Using SSL and native LDAP
    2.) Using Kerberos (requires Kerberos to be setup)
    3.) Using NetUserSetInfo api call.

    It tries all of them in order (obviously stopping if successful). What happens on Win2k, is that the first two fail and then it tries the last one. The problem is that the credentials specified on the DirectoryEntry sometimes (maybe always) do not transfer to this call. So, ASPNET account ends up making the call, and it will fail with the error you see.

    Here is what you can try:
    Try 
    
    Const ADS_UF_ACCOUNTDISABLE As Integer = &H2

    Dim user As New DirectoryEntry() '(Pathname)
    Dim entry As New DirectoryServices.DirectoryEntry("LDAP://Domain.com")
    Dim Serchr As New System.DirectoryServices.DirectorySearcher(entry)

    Serchr.Filter = ("(samAccountName=" & NetID & ")")

    Dim sr as SearchResult = Serchr.FindOne()

    If (Not(sr Is Nothing)) Then

    user = sr.GetDirectoryEntry()
    user.Username = "DOMAIN\Admin" 'valid Admin User