Reset AD user account password using a privileged account

0

I am trying to code a way to let a help desk person with an account that does not have sufficient permissions to reset passwords to do that by embedding another account in the code.

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim RootDSE As New DirectoryServices.DirectoryEntry("LDAP://something.com/OU=COW,DC=spmething,DC=com")
    Dim DomainDN As String = RootDSE.Properties("DefaultNamingContext").Value
    Dim ADEntry As New DirectoryServices.DirectoryEntry("LDAP://" & "DC=something,DC=com")
    Dim ADSearch As New System.DirectoryServices.DirectorySearcher(ADEntry)

    If RadioButton1.Checked = True Then
        ADSearch.Filter = ("(samAccountName=" & Loginnames.Text & ")")
        ADSearch.SearchScope = SearchScope.Subtree
        Dim UserFound As SearchResult = ADSearch.FindOne()
        If Not IsNothing(UserFound) Then
            Dim UserDirectoryEntry As DirectoryEntry = UserFound.GetDirectoryEntry
            UserDirectoryEntry.Invoke("SetPassword", New Object() {TextBox2.Text})
            '...
            email = UserFound.GetDirectoryEntry.Properties("userPrincipalName").Value
            MsgBox("Password has been rest!")

        End If
    End If

I need to do that using a user other than the helpdesk because the helpdesk user does not have permission to do that. And we do not want to delegate anything to him.

The error he is getting now is: 0x80070005 (E_ACCESSDENIED)

vb.net
active-directory
ldap
impersonation
asked on Stack Overflow Aug 22, 2018 by user2085339 • edited Aug 23, 2018 by Theo

1 Answer

0

I did this once (long time ago) in VB6 using

Dim objDSO     As IADsOpenDSObject
Dim objUser    As IADsUser

Set objDSO = GetObject("LDAP:")
Set objUser = objDSO.OpenDSObject("LDAP://" & strUser, DELEGATE_ACCOUNTNAME, DELEGATE_PASSWORD, ADS_SECURE_AUTHENTICATION)

so it must also be doable in VB.Net since the IADs interface defines the basic object (properties and methods) of any ADSI object. Both DirectoryEntry and DirectorySearcher use the Active Directory Services Interfaces (ADSI) technology according to this

Indeed, the DirectoryEntry constructor can be extended with a username and password to use for the binding, other than the user that is currently running the script or application. So instead of

Dim ADEntry As New DirectoryServices.DirectoryEntry("LDAP://" & "DC=something,DC=com")

try this

Dim ADEntry As New DirectoryServices.DirectoryEntry("LDAP://" & "DC=something,DC=com", DELEGATE_ACCOUNTNAME, DELEGATE_PASSWORD, 1)

where '1' is the value for the System.DirectoryServices AuthenticationType "Secure".

This DELEGATE is a user you set up in your domain where you make sure he/she/it has permisions to reset passwords and unlock user accounts (see the Note below).

The DELEGATE_PASSWORD is given in plain text, so you'll need some way of hiding that from the helpdesk user! Now the rest of the code in your Button1_Click sub should use this delegate's credentials to find and set the password.

Note: Users generally call the helpdesk about their password only after they have tried too many times and their account has been locked. Your function should therefore also unlock the account before setting a new password. You can check if the account is locked by inspecting the (int64) lockoutTime ldap attribute of the user. To unlock the account, just set this value to 0L

answered on Stack Overflow Aug 25, 2018 by Theo

User contributions licensed under CC BY-SA 3.0