Robert Gijsen
unread,Jan 12, 2012, 1:03:57 PM1/12/12Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Cassia Users
I tried with two 'versions' of impersonation (both found from
internet). Both do the same. Sorry for the long reply here. I've split
the two different types I tried with a long line. I am currently on
the upper one.
Public Class AliasAccount
Private _username, _password, _domainname As String
Private _tokenHandle As New IntPtr(0)
Private _dupeTokenHandle As New IntPtr(0)
Private _impersonatedUser As
System.Security.Principal.WindowsImpersonationContext
Public Sub New(ByVal username As String, ByVal password As String)
Dim nameparts() As String = username.Split("\")
If nameparts.Length > 1 Then
_domainname = nameparts(0)
_username = nameparts(1)
Else
_username = username
End If
_password = password
End Sub
Public Sub New(ByVal username As String, ByVal password As String,
ByVal domainname As String)
_username = username
_password = password
_domainname = domainname
End Sub
' <summary>
' This logon type is intended for users who will be interactively
' using the computer, such as a user being logged on by a
' terminal server, remote shell, or similar process.
' This logon type has the additional expense of caching logon
' information for disconnected operations; therefore, it is
' inappropriate for some client/server applications, such as a
' mail server.
' </summary>
' Interactive = 2,
' <summary>
' This logon type is intended for high performance servers to
' authenticate plaintext passwords.
' The LogonUser function does not cache credentials for this
' logon type.
' </summary>
' Network = 3,
' <summary>
' This logon type is intended for batch servers, where processes
' may be executing on behalf of a user without their direct
' intervention. This type is also for higher performance servers
' that process many plaintext authentication attempts at a time,
' such as mail or Web servers.
' The LogonUser function does not cache credentials for this
' logon type.
' </summary>
' Batch = 4,
' <summary>
' Indicates a service-type logon. The account provided must have
' the service privilege enabled.
' </summary>
' Service = 5,
' <summary>
' This logon type is for GINA DLLs that log on users who will be
' interactively using the computer.
' This logon type can generate a unique audit record that shows
' when the workstation was unlocked.
' </summary>
' Unlock = 7,
' <summary>
' This logon type preserves the name and password in the
' authentication package, which allows the server to make
' connections to other network servers while impersonating the
' client. A server can accept plaintext credentials from a
' client, call LogonUser, verify that the user can access the
' system across the network, and still communicate with other
' servers.
' NOTE: Windows NT: This value is not supported.
' </summary>
' NetworkCleartext = 8,
' <summary>
' This logon type allows the caller to clone its current token
' and specify new credentials for outbound connections. The new
' logon session has the same local identifier but uses different
' credentials for other network connections.
' NOTE: This logon type is supported only by the
' LOGON32_PROVIDER_WINNT50 logon provider.
' NOTE: Windows NT: This value is not supported.
' </summary>
' NewCredentials = 9
Public Sub BeginImpersonation()
Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Const LOGONTYPE As Integer = 9
Const SecurityImpersonation As Integer = 2
Dim win32ErrorNumber As Integer
_tokenHandle = IntPtr.Zero
_dupeTokenHandle = IntPtr.Zero
If Not LogonUser(_username, _domainname, _password, LOGONTYPE,
LOGON32_PROVIDER_DEFAULT, _tokenHandle) Then
win32ErrorNumber =
System.Runtime.InteropServices.Marshal.GetLastWin32Error()
Throw New ImpersonationException(win32ErrorNumber,
GetErrorMessage(win32ErrorNumber), _username, _domainname)
End If
If Not DuplicateToken(_tokenHandle, SecurityImpersonation,
_dupeTokenHandle) Then
win32ErrorNumber =
System.Runtime.InteropServices.Marshal.GetLastWin32Error()
CloseHandle(_tokenHandle)
Throw New ImpersonationException(win32ErrorNumber, "Unable
to duplicate token!", _username, _domainname)
End If
Dim newId As New
System.Security.Principal.WindowsIdentity(_dupeTokenHandle)
_impersonatedUser = newId.Impersonate()
End Sub
Public Sub EndImpersonation()
If Not _impersonatedUser Is Nothing Then
_impersonatedUser.Undo()
_impersonatedUser = Nothing
If Not System.IntPtr.op_Equality(_tokenHandle,
IntPtr.Zero) Then
CloseHandle(_tokenHandle)
End If
If Not System.IntPtr.op_Equality(_dupeTokenHandle,
IntPtr.Zero) Then
CloseHandle(_dupeTokenHandle)
End If
End If
End Sub
Public ReadOnly Property username() As String
Get
Return _username
End Get
End Property
Public ReadOnly Property domainname() As String
Get
Return _domainname
End Get
End Property
Public ReadOnly Property currentWindowsUsername() As String
Get
Return
System.Security.Principal.WindowsIdentity.GetCurrent().Name
End Get
End Property
#Region "Exception Class"
Public Class ImpersonationException
Inherits System.Exception
Public ReadOnly win32ErrorNumber As Integer
Public Sub New(ByVal win32ErrorNumber As Integer, ByVal msg As
String, ByVal username As String, ByVal domainname As String)
MyBase.New(String.Format("Impersonation of {1}\{0} failed!
[{2}] {3}", username, domainname, win32ErrorNumber, msg))
Me.win32ErrorNumber = win32ErrorNumber
End Sub
End Class
#End Region
#Region "External Declarations and Helpers"
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
Private Declare Auto Function DuplicateToken Lib
"advapi32.dll" (ByVal ExistingTokenHandle As IntPtr, _
ByVal SECURITY_IMPERSONATION_LEVEL As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As Boolean
Private Declare Auto Function CloseHandle Lib
"kernel32.dll" (ByVal handle As IntPtr) As Boolean
<System.Runtime.InteropServices.DllImport("kernel32.dll")> _
Private Shared Function FormatMessage(ByVal dwFlags As Integer,
ByRef lpSource As IntPtr, _
ByVal dwMessageId As Integer, ByVal dwLanguageId As
Integer, ByRef lpBuffer As [String], _
ByVal nSize As Integer, ByRef Arguments As IntPtr) As
Integer
End Function
Private Function GetErrorMessage(ByVal errorCode As Integer) As
String
Dim FORMAT_MESSAGE_ALLOCATE_BUFFER As Integer = &H100
Dim FORMAT_MESSAGE_IGNORE_INSERTS As Integer = &H200
Dim FORMAT_MESSAGE_FROM_SYSTEM As Integer = &H1000
Dim messageSize As Integer = 255
Dim lpMsgBuf As String = Nothing
Dim dwFlags As Integer = FORMAT_MESSAGE_ALLOCATE_BUFFER Or
FORMAT_MESSAGE_FROM_SYSTEM Or FORMAT_MESSAGE_IGNORE_INSERTS
Dim ptrlpSource As IntPtr = IntPtr.Zero
Dim prtArguments As IntPtr = IntPtr.Zero
Dim retVal As Integer = FormatMessage(dwFlags, ptrlpSource,
errorCode, 0, lpMsgBuf, messageSize, prtArguments)
If 0 = retVal Then
Throw New System.Exception("Failed to format message for
error code " + errorCode.ToString() + ". ")
End If
Return lpMsgBuf
End Function
#End Region
End Class
-------------------------------------------------------------------------------------------------------------------------------------------------------------
second version below
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Imports System.Threading
Imports System.Configuration
Imports SR = System.Reflection
Imports System.Text
Imports System.Security.Principal
Public Class Utilities
Private Const LOGON32_PROVIDER_DEFAULT As Integer = 0
Private Const LOGON32_LOGON_INTERACTIVE As Integer = 2
Private Const LOGON32_LOGON_NETWORK As Integer = 3
Private Const LOGON32_LOGON_BATCH As Integer = 4
Private Const LOGON32_LOGON_SERVICE As Integer = 5
Private Const LOGON32_LOGON_UNLOCK As Integer = 7
Private Const LOGON32_LOGON_NETWORK_CLEARTEXT As Integer = 8
Private Const LOGON32_LOGON_NEW_CREDENTIALS As Integer = 9
Private Shared 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
' NOTE:
' The identity of the process that impersonates a specific user on
a thread must have
' "Act as part of the operating system" privilege. If the the
Aspnet_wp.exe process runs
' under a the ASPNET account, this account does not have the
required privileges to
' impersonate a specific user. This information applies only to
the .NET Framework 1.0.
' This privilege is not required for the .NET Framework 1.1.
'
' Sample call:
'
' If impersonateValidUser("username", "domain", "password")
Then
' 'Insert your code here.
'
' undoImpersonation()
' Else
' 'Impersonation failed. Include a fail-safe mechanism
here.
' End If
'
Public Shared Function ImpersonateValidUser(ByVal strUserName As
String, _
ByVal strDomain As String, ByVal strPassword As String) As
Boolean
Dim token As IntPtr = IntPtr.Zero
Dim tokenDuplicate As IntPtr = IntPtr.Zero
Dim tempWindowsIdentity As WindowsIdentity
ImpersonateValidUser = False
If RevertToSelf() <> 0 Then
If LogonUserA(strUserName, strDomain, _
strPassword, _
LOGON32_LOGON_NEW_CREDENTIALS, _
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
Public Shared Sub UndoImpersonation()
ImpersonationContext.Undo()
End Sub
End Class