R
Ron
I have an application that ran fine under Server 2003 x32 and now has
intermittent failures under Windows Server 2008 x64.
The application allow users to reset their password in the active directory
when the have lost their password entirely.
When the problem occurrs, no error is returned, but the password is not reset.
I suspect that the problem may be with the impersonation, but I have not
been able to locate any documentation on the correct way to accomplish an
impersonation under Windows Server 2008. Any help would be appreciated.
There was no change to the domain when we started using Windows Server 2008
and the website appears to run just fine on the old Windows Server 2003
machine.
One issue that I am not sure of…the impersonator uses the advapi32.dll and
kernel32.dll libraries. Note that the machine is a Windows Server 2008 x64
machine.
Basically it does the following.
1) Impersonate a user with password set access to the OU that contains the
user.
2) objUSer.AuthenticationType = AuthenticationTypes.Secure
3) objUSer.Invoke("SetPassword", strPassword)
4) objUSer.CommitChanges()
5) Undo Impersonation
Impersonation is by:
Public Function ImpersonateUser( _
ByVal Domain As String, _
ByVal userName As String, _
ByVal password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
Dim iError As Integer
Dim ret As Integer
Dim strErr As String
Try
If RevertToSelf() Then
iError = LogonUserA(userName, Domain, password,
LogonType.LOGON32_LOGON_INTERACTIVE, _
LogonProvider.LOGON32_PROVIDER_DEFAULT, token)
If iError <> 0 Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
impersonationContext = tempWindowsIdentity.Impersonate()
If Not impersonationContext Is Nothing Then
ImpersonateUser = True
Else
ret = Marshal.GetLastWin32Error()
strErr = "No Context returned:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
Else
CloseHandle(token)
ret = Marshal.GetLastWin32Error()
strErr = "Failed To Duplicate Token:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
Else
ret = Marshal.GetLastWin32Error()
strErr = "LogonUser failed:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
Else
ret = Marshal.GetLastWin32Error()
strErr = "RevertToSelf Failed:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
If Not tokenDuplicate.Equals(IntPtr.Zero) Then
CloseHandle(tokenDuplicate)
End If
If Not token.Equals(IntPtr.Zero) Then
CloseHandle(token)
End If
Catch appEx As ApplicationException
sError = appEx.Message
'objErrorLog.WriteTOErrorLog(sLoginUserName, Err.Number, appEx.Source,
appEx.TargetSite.Name, appEx.Message, appEx.StackTrace)
ImpersonateUser = False
End Try
End Function
intermittent failures under Windows Server 2008 x64.
The application allow users to reset their password in the active directory
when the have lost their password entirely.
When the problem occurrs, no error is returned, but the password is not reset.
I suspect that the problem may be with the impersonation, but I have not
been able to locate any documentation on the correct way to accomplish an
impersonation under Windows Server 2008. Any help would be appreciated.
There was no change to the domain when we started using Windows Server 2008
and the website appears to run just fine on the old Windows Server 2003
machine.
One issue that I am not sure of…the impersonator uses the advapi32.dll and
kernel32.dll libraries. Note that the machine is a Windows Server 2008 x64
machine.
Basically it does the following.
1) Impersonate a user with password set access to the OU that contains the
user.
2) objUSer.AuthenticationType = AuthenticationTypes.Secure
3) objUSer.Invoke("SetPassword", strPassword)
4) objUSer.CommitChanges()
5) Undo Impersonation
Impersonation is by:
Public Function ImpersonateUser( _
ByVal Domain As String, _
ByVal userName As String, _
ByVal password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
Dim iError As Integer
Dim ret As Integer
Dim strErr As String
Try
If RevertToSelf() Then
iError = LogonUserA(userName, Domain, password,
LogonType.LOGON32_LOGON_INTERACTIVE, _
LogonProvider.LOGON32_PROVIDER_DEFAULT, token)
If iError <> 0 Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
impersonationContext = tempWindowsIdentity.Impersonate()
If Not impersonationContext Is Nothing Then
ImpersonateUser = True
Else
ret = Marshal.GetLastWin32Error()
strErr = "No Context returned:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
Else
CloseHandle(token)
ret = Marshal.GetLastWin32Error()
strErr = "Failed To Duplicate Token:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
Else
ret = Marshal.GetLastWin32Error()
strErr = "LogonUser failed:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
Else
ret = Marshal.GetLastWin32Error()
strErr = "RevertToSelf Failed:" & ErrorMessage(ret)
Throw New ApplicationException(strErr)
End If
If Not tokenDuplicate.Equals(IntPtr.Zero) Then
CloseHandle(tokenDuplicate)
End If
If Not token.Equals(IntPtr.Zero) Then
CloseHandle(token)
End If
Catch appEx As ApplicationException
sError = appEx.Message
'objErrorLog.WriteTOErrorLog(sLoginUserName, Err.Number, appEx.Source,
appEx.TargetSite.Name, appEx.Message, appEx.StackTrace)
ImpersonateUser = False
End Try
End Function