Public Class WindowsImpersonator
Public Delegate Function DelegateImpersonateExecuteFunction( _
ByVal args() As Object, _
ByRef ReturnValue As Object, _
ByRef ExceptionMessage As String) As Integer
#Region " Win32 API Declarations"
Private Declare Auto Function LogonUser Lib "advapi32.dll" ( _
ByVal lpszUsername As [String], _
ByVal lpszDomain As [String], _
ByVal lpszPassword As [String], _
ByVal dwLogonType As Integer, _
ByVal dwLogonProvider As Integer, _
ByRef phToken As IntPtr) As Boolean
Public Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As IntPtr) As Boolean
Public Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
ByVal ExistingTokenHandle As IntPtr, _
ByVal SECURITY_IMPERSONATION_LEVEL As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As Boolean
#End Region
' If you incorporate this code into a DLL, be sure to demand FullTrust.
' _
Public Shared Function Impersonate(ByVal UserName As String, _
ByVal Password As String, _
ByVal Domain As String, _
ByVal ExecuteFunction As DelegateImpersonateExecuteFunction, _
ByVal FunctionArguments() As Object, _
ByRef FunctionReturnValue As Object, _
ByRef ExceptionMessage As String) As Integer
Dim TokenHandle As New IntPtr(0)
Dim DupTokenHandle As New IntPtr(0)
Dim ret As Integer
Try
Const LOGON32_PROVIDER_DEFAULT As Integer = 0
'This parameter causes LogonUser to create a primary token.
Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Const SecurityImpersonation As Integer = 2
TokenHandle = IntPtr.Zero
DupTokenHandle = IntPtr.Zero
'Call LogonUser to obtain a handle to an access token.
'Windows 2000 raises error 1314 : 'A required privilege is not held by the client'
If Not LogonUser(UserName, Domain, Password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, TokenHandle) Then
Dim ret1 As Integer = System.Runtime.InteropServices.Marshal.GetLastWin32Error()
Throw New Exception(String.Format("{0}Error: [{1}]{0}{2}", Environment.NewLine, ret1, New System.ComponentModel.Win32Exception(ret1).Message))
End If
Debug.WriteLine(("Value of Windows NT token: " & TokenHandle.ToString()))
Debug.WriteLine(("Before impersonation: " & System.Security.Principal.WindowsIdentity.GetCurrent().Name))
If Not DuplicateToken(TokenHandle, SecurityImpersonation, DupTokenHandle) Then
CloseHandle(TokenHandle)
Throw New Exception("Error in trying to duplicate token.")
End If
' The token that is passed to the following constructor must
' be a primary token in order to use it for impersonation.
Dim NewId As New System.Security.Principal.WindowsIdentity(DupTokenHandle)
Dim ImpersonatedUser As System.Security.Principal.WindowsImpersonationContext = NewId.Impersonate()
Debug.WriteLine(("After impersonation: " & System.Security.Principal.WindowsIdentity.GetCurrent().Name))
If Not ExecuteFunction Is Nothing Then
If ExecuteFunction(FunctionArguments, FunctionReturnValue, ExceptionMessage) = -1 Then
ret = -1
End If
End If
' Stop impersonating the user.
ImpersonatedUser.Undo()
Debug.WriteLine(("After Undo: " & System.Security.Principal.WindowsIdentity.GetCurrent().Name))
Catch ex As Exception
ret = -1
ExceptionMessage = ex.ToString
Finally
' Free the tokens.
If Not System.IntPtr.op_Equality(TokenHandle, IntPtr.Zero) Then
CloseHandle(TokenHandle)
End If
If Not System.IntPtr.op_Equality(DupTokenHandle, IntPtr.Zero) Then
CloseHandle(DupTokenHandle)
End If
End Try
Return ret
End Function
End Class |