Private Sub ChangeUserADPassword(ByVal Username As String, ByVal Password As String, ByVal newPwd As String)
Dim dcDNS As String = "whatever.com"
Dim rootDN As String
Dim rootDSE As DirectoryEntry
Dim searchRoot As DirectoryEntry
Dim userEntry As DirectoryEntry
Dim searcher As DirectorySearcher
Dim results As SearchResultCollection
Dim result As SearchResult
Dim oldPassword As String = Password
Dim newPassword As String = newPwd
Try
'=========================================================================
'Here I am binding the directory to the root with the current
'users name and password instead of using an admin login to authenticate
'The reason for this is that the users are not admin and only admin
'can use the setpassword invoke method. thus, authenticated users will
'use the change password method
'note the authenicationtypes here
'you need to either use SecureSocketsLayer or Kerberos (Secure + Sealing)
result = Nothing
rootDSE = New DirectoryEntry(String.Format("LDAP://{0}/rootDSE", _
dcDNS), Username, oldPassword, AuthenticationTypes.Secure Or _
AuthenticationTypes.Sealing Or AuthenticationTypes.ServerBind)
rootDN = DirectCast(rootDSE.Properties("defaultNamingContext").Value, String)
searchRoot = New DirectoryEntry(String.Format("LDAP://{0}/{1}", _
dcDNS, rootDN), Username, oldPassword, AuthenticationTypes.Secure Or _
AuthenticationTypes.Sealing Or AuthenticationTypes.ServerBind)
'==================================================================
'------------------------------------------------------------------------
'Find the user by their username in the directory using the
'DirectorySearcher()
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
'only use this method on .NET 1.1 or higher
'otherwise, get the adsPath value and build a new
'DirectoryEntry with the supplied credentials
userEntry = result.GetDirectoryEntry()
Exit For
'this is redundant because sAMAccountName is unique
'in the domain, but it is done for clarity
'Bind the user's DirectoryEntry (found from result search)
Next
'result = Nothing
userEntry = result.GetDirectoryEntry()
If userEntry Is Nothing Then
Label4.Text = "User not found in this domain."
Exit Sub
End If
'Invoke the ChangePassword method (not the SetPassword method, since that
'is used by admins to reset a password)
userEntry.Invoke("ChangePassword", New Object() {oldPassword, newPassword})
userEntry.CommitChanges()
'****************************************************
Label4.Text = "Password Changed Successfully"
If Not Session("User") Is Nothing Then
txtuser.Text = CStr(Session("User"))
GetUserPasswordADInfo(CStr(Session("User")))
Else
GetUserPasswordADInfo(Trim(txtuser.Text))
End If
Catch ex As Exception 'System.Reflection.TargetInvocationException
Label4.Text = ex.Message
Finally 'these prevent other memory leaks
userEntry = Nothing
If Not userEntry Is Nothing Then userEntry.Dispose()
results = Nothing
If Not results Is Nothing Then results.Dispose()
searcher = Nothing
If Not searcher Is Nothing Then searcher.Dispose()
searchRoot = Nothing
If Not searchRoot Is Nothing Then searchRoot.Dispose()
rootDSE = Nothing
If Not rootDSE Is Nothing Then rootDSE.Dispose()
End Try
End Sub