Hello ,
Are you sure that the impersonation class works ? ( did you confirm that by
for instance accessing a directory through code that only the impersonated
user has access to and not the logged on user )
I use impersonation in my company but there i read and write to a network
share that is only accessible by my impersonated user
my code returns if the impersonation succeeded .
'Michel Posseth [MCP] 10-07-2008 , written to run parts of code in another
user context during runtime
Imports System.Security
Imports System.Security.Principal
Imports System.Runtime.InteropServices
Public Class ImpersonateSpecificUser
Implements IDisposable
Private Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Private Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Private impersonationContext As WindowsImpersonationContext
Declare Function LogonUserA 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 Integer
Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
ByVal ExistingTokenHandle As IntPtr, _
ByVal ImpersonationLevel As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As Integer
Declare Auto Function RevertToSelf Lib "advapi32.dll" () As Long
Declare Auto Function CloseHandle Lib "kernel32.dll" (ByVal handle As
IntPtr) As Long
Public Event eSpecificUserImpersonation(ByVal Success As Boolean)
Private _Impersonated As Boolean
''' <summary>
''' Gets or sets a value indicating whether this <see
cref="ImpersonateSpecificUser" /> is impersonated.
''' </summary>
''' <value><c>true</c> if impersonated; otherwise, <c>false</c>.</value>
Public Property Impersonated() As Boolean
Get
Return _Impersonated
End Get
Private Set(ByVal value As Boolean)
_Impersonated = value
End Set
End Property
''' <summary>
''' Initializes a new instance of the <see cref="ImpersonateSpecificUser" />
class.
''' </summary>
''' Name of the user.
''' The password.
''' The domain.
Public Sub New(ByVal UserName As String, ByVal Password As String, ByVal
Domain As String)
If impersonateValidUser(UserName, Domain, Password) Then
RaiseEvent eSpecificUserImpersonation(True)
Else
'Your impersonation failed. Therefore, include a fail-safe mechanism here.
RaiseEvent eSpecificUserImpersonation(False)
End If
End Sub
''' <summary>
''' Impersonates the valid user.
''' </summary>
''' Name of the user.
''' The domain.
''' The password.
''' <returns></returns>
Private Function impersonateValidUser(ByVal userName As String, ByVal domain
As String, ByVal password As String) As Boolean
Dim tempWindowsIdentity As WindowsIdentity
Dim token As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
impersonateValidUser = False
If RevertToSelf() Then
If LogonUserA(userName, domain, password, LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT, token) <> 0 Then
If DuplicateToken(token, 2, tokenDuplicate) <> 0 Then
tempWindowsIdentity = New WindowsIdentity(tokenDuplicate)
impersonationContext = tempWindowsIdentity.Impersonate()
If Not impersonationContext Is Nothing Then
impersonateValidUser = True
End If
End If
End If
End If
If Not tokenDuplicate.Equals(IntPtr.Zero) Then
CloseHandle(tokenDuplicate)
End If
If Not token.Equals(IntPtr.Zero) Then
CloseHandle(token)
End If
End Function
''' <summary>
''' Undoes the impersonation.
''' </summary>
Public Sub undoImpersonation()
impersonationContext.Undo()
Impersonated = False
End Sub
Private disposedValue As Boolean = False ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(ByVal disposing As Boolean)
If Not Me.disposedValue Then
If disposing Then
' TODO: free other state (managed objects).
End If
If Impersonated Then 'wees er zeer van dat we weer in een normale context
draaien
undoImpersonation()
End If
' TODO: free your own state (unmanaged objects).
' TODO: set large fields to null.
End If
Me.disposedValue = True
End Sub
' This code added by Visual Basic to correctly implement the disposable
pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(ByVal disposing As
Boolean) above.
Dispose(True)
GC.SuppressFinalize(Me)
End Sub
''' <summary>
''' Impersonates the specific user_e specific user impersonation.
''' </summary>
''' if set to <c>true</c> [success].
Private Sub ImpersonateSpecificUser_eSpecificUserImpersonation(ByVal Success
As Boolean) Handles Me.eSpecificUserImpersonation
Me.Impersonated = Success
End Sub
End Class
Usage :
Using UImp As New
UserImpersonate.ImpersonateSpecificUser("Username","Password","Domain")
IF UImp.Impersonated Then
'all code here that must run in the user context or the method calls to
other procedures
End If
End Using
after this point the code runs in "Normall" modus
HTH
Michel Posseth [MCP]