A
ABSMunkee
I have a vb.net dll that has two functions: one allows a user to change
their password in AD, the second allows the user to view their
distinguishedname (based on their samaccountname). Both bind via an
SSL connection and appear to work well.
I am implementing the dll through an asp interface on the DC that holds
the fsmo role of PDC in a domain with several DCs with a replication
delay of up to an hour between the DCs.
The issue I am seeing is that after a user successfully changes their
password they are able to successfully query AD for their distinguished
name with their OLD password for awhile (I am assuming until
replication notifies whichever server they are authenticating against
that their password has changed - at which point the dll throws an
"unknown username or bad password" error). The problem is that I am
pointing to the PDC emulator (the server that the asp/dll runs on) to
make the change - so would ASSUME that this same box authenticates the
username and password... ??
Any thoughts would be welcome.
Code snippet below:
Private iRtnCodeVal As Int32 = 1
Private sDirRoot As String = "dc=mydomain,dc=com"
Private sServer As String = "PDCEmulatorDC/"
Private sDomain As String = "MyDomain"
Public Function ChangePW(ByVal uName As String, ByVal oldPass As
String, ByVal newPass As String) As Boolean
Dim uDN As String = GetDN(uName, sDomain & "\" & uName,
oldPass)
If iRtnCodeVal <> 0 Then
ChangePW = False
Exit Function
End If
Dim uDE As New DirectoryEntry("LDAP://" & sServer & uDN)
uDE.AuthenticationType = AuthenticationTypes.SecureSocketsLayer
uDE.Username = sDomain & "\" & uName
uDE.Password = oldPass
Dim iPWChgRtn As Integer
Try
iPWChgRtn = uDE.Invoke("ChangePassword", New Object()
{oldPass, newPass})
Catch ex As Exception
iRtnCodeVal = Err.Number()
ChangePW = False
uDE.Close()
Exit Function
End Try
If iPWChgRtn = 0 Then
iRtnCodeVal = 0
ChangePW = True
Else
ChangePW = False
End If
uDE.Close()
End Function
'------------------
Public Function GetDN(ByVal nameToFind As String, ByVal authU As
String, ByVal authPW As String, Optional ByVal useSSL As Boolean =
True) As String
If InStr(authU, "\") = 0 Then 'Will come in WITH <domain>\
from ChangePW
authU = sDomain & "\" & authU
End If
Dim theEntry As New DirectoryEntry("LDAP://" & sServer &
sDirRoot)
If useSSL Then theEntry.AuthenticationType =
AuthenticationTypes.SecureSocketsLayer
theEntry.Username = authU
theEntry.Password = authPW
Dim theSearcher As New DirectorySearcher(theEntry)
theSearcher.SearchScope = SearchScope.Subtree
theSearcher.Filter = "(&(samaccountname=" & nameToFind & "))"
theSearcher.PropertiesToLoad.Add("distinguishedname")
Try
Dim Rslt As SearchResult = theSearcher.FindOne
If Rslt Is Nothing = False Then
Dim prop As Object
Dim outTxt As String
For Each prop In Rslt.Properties("distinguishedname")
outTxt = prop.ToString
Next
GetDN = outTxt
iRtnCodeVal = 0
Else
iRtnCodeVal = 2
End If
Catch ex As Exception
GetDN = ""
iRtnCodeVal = Err.Number()
End Try
theEntry.Close()
End Function
their password in AD, the second allows the user to view their
distinguishedname (based on their samaccountname). Both bind via an
SSL connection and appear to work well.
I am implementing the dll through an asp interface on the DC that holds
the fsmo role of PDC in a domain with several DCs with a replication
delay of up to an hour between the DCs.
The issue I am seeing is that after a user successfully changes their
password they are able to successfully query AD for their distinguished
name with their OLD password for awhile (I am assuming until
replication notifies whichever server they are authenticating against
that their password has changed - at which point the dll throws an
"unknown username or bad password" error). The problem is that I am
pointing to the PDC emulator (the server that the asp/dll runs on) to
make the change - so would ASSUME that this same box authenticates the
username and password... ??
Any thoughts would be welcome.
Code snippet below:
Private iRtnCodeVal As Int32 = 1
Private sDirRoot As String = "dc=mydomain,dc=com"
Private sServer As String = "PDCEmulatorDC/"
Private sDomain As String = "MyDomain"
Public Function ChangePW(ByVal uName As String, ByVal oldPass As
String, ByVal newPass As String) As Boolean
Dim uDN As String = GetDN(uName, sDomain & "\" & uName,
oldPass)
If iRtnCodeVal <> 0 Then
ChangePW = False
Exit Function
End If
Dim uDE As New DirectoryEntry("LDAP://" & sServer & uDN)
uDE.AuthenticationType = AuthenticationTypes.SecureSocketsLayer
uDE.Username = sDomain & "\" & uName
uDE.Password = oldPass
Dim iPWChgRtn As Integer
Try
iPWChgRtn = uDE.Invoke("ChangePassword", New Object()
{oldPass, newPass})
Catch ex As Exception
iRtnCodeVal = Err.Number()
ChangePW = False
uDE.Close()
Exit Function
End Try
If iPWChgRtn = 0 Then
iRtnCodeVal = 0
ChangePW = True
Else
ChangePW = False
End If
uDE.Close()
End Function
'------------------
Public Function GetDN(ByVal nameToFind As String, ByVal authU As
String, ByVal authPW As String, Optional ByVal useSSL As Boolean =
True) As String
If InStr(authU, "\") = 0 Then 'Will come in WITH <domain>\
from ChangePW
authU = sDomain & "\" & authU
End If
Dim theEntry As New DirectoryEntry("LDAP://" & sServer &
sDirRoot)
If useSSL Then theEntry.AuthenticationType =
AuthenticationTypes.SecureSocketsLayer
theEntry.Username = authU
theEntry.Password = authPW
Dim theSearcher As New DirectorySearcher(theEntry)
theSearcher.SearchScope = SearchScope.Subtree
theSearcher.Filter = "(&(samaccountname=" & nameToFind & "))"
theSearcher.PropertiesToLoad.Add("distinguishedname")
Try
Dim Rslt As SearchResult = theSearcher.FindOne
If Rslt Is Nothing = False Then
Dim prop As Object
Dim outTxt As String
For Each prop In Rslt.Properties("distinguishedname")
outTxt = prop.ToString
Next
GetDN = outTxt
iRtnCodeVal = 0
Else
iRtnCodeVal = 2
End If
Catch ex As Exception
GetDN = ""
iRtnCodeVal = Err.Number()
End Try
theEntry.Close()
End Function