Re: System.Security.Principal.WindowsImpersonation
From: borgc (borgc_at_polarfab.com)
Date: 07/29/03
- Next message: Ivan Medvedev [MS]: "Re: TripleDESCryptoServiceProvider vs. CryptoAPI"
- Previous message: Michel Gallant: "Re: How to get KeyUsage field given .NET X509Certificate instance?"
- In reply to: Shel Blauman [MSFT]: "Re: System.Security.Principal.WindowsImpersonation"
- Next in thread: Shel Blauman [MSFT]: "Re: System.Security.Principal.WindowsImpersonation"
- Reply: Shel Blauman [MSFT]: "Re: System.Security.Principal.WindowsImpersonation"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Date: Tue, 29 Jul 2003 07:01:06 -0700
Thanks for the Code, but I have the same problem with
this code, that I had with my original code. The User is
impersonated, but the privledges for that user are not
transfered. If any one has any additional suggestions - I
would appreciate the help.
Thanks
Chet
>-----Original Message-----
>This code should work on XP.
>
>Shel
>
>[Visual Basic]
>
> ' This sample demonstrates the use of the
WindowsIdentity class to
>impersonate a user.
>' IMPORTANT NOTES:
>' This sample can be run only on Windows XP. The
default Windows 2000
>security policy
>' prevents this sample from executing properly, and
changing the policy to
>allow
>' proper execution presents a security risk.
>' This sample requests the user to enter a password on
the console screen.
>' Because the console window does not support methods
allowing the password
>to be masked,
>' it will be visible to anyone viewing the screen.
>
>Imports System
>Imports System.Runtime.InteropServices
>Imports System.Security.Principal
>Imports System.Security.Permissions
>Imports Microsoft.VisualBasic
><Assembly: SecurityPermissionAttribute
(SecurityAction.RequestMinimum,
>UnmanagedCode:=True), _
> Assembly: PermissionSetAttribute
(SecurityAction.RequestMinimum,
>Name:="FullTrust")>
>Module Module1
>
> Public Class ImpersonationDemo
>
> 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
>
> <DllImport("kernel32.dll")> _
> Public 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
>
> 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
>
> 'GetErrorMessage formats and returns an error
message
> 'corresponding to the input errorCode.
> Public Shared 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
> 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 Exception("Failed to format
message for error code
>" + errorCode.ToString() + ". ")
> End If
>
> Return lpMsgBuf
> End Function 'GetErrorMessage
> ' Test harness.
> ' If you incorporate this code into a DLL, be
sure to demand
>FullTrust.
> <PermissionSetAttribute(SecurityAction.Demand,
Name:="FullTrust")> _
> Public Overloads Shared Sub Main(ByVal args() As
String)
>
> Dim tokenHandle As New IntPtr(0)
> Dim dupeTokenHandle As New IntPtr(0)
> Try
>
>
> Dim userName, domainName As String
>
> ' Get the user token for the specified
user, domain, and
>password using the
> ' unmanaged LogonUser method.
> ' The local machine name can be used for
the domain name to
>impersonate a user on this machine.
> Console.Write("Enter the name of a
domain on which to log
>on: ")
> domainName = Console.ReadLine()
>
> Console.Write("Enter the login of a user
on {0} that you
>wish to impersonate: ", domainName)
> userName = Console.ReadLine()
>
> Console.Write("Enter the password for
{0}: ", userName)
>
> 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
> dupeTokenHandle = IntPtr.Zero
>
> ' Call LogonUser to obtain a handle to
an access token.
> Dim returnValue As Boolean = LogonUser
(userName, domainName,
>Console.ReadLine(), LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
>tokenHandle)
>
> Console.WriteLine("LogonUser called.")
>
> If False = returnValue Then
> Dim ret As Integer =
Marshal.GetLastWin32Error()
> Console.WriteLine("LogonUser failed
with error code :
>{0}", ret)
> Console.WriteLine(ControlChars.Cr
+ "Error: [{0}] {1}" +
>ControlChars.Cr, ret, GetErrorMessage(ret))
>
> Return
> End If
>
> Dim success As String
> If returnValue Then success = "Yes" Else
success = "No"
> Console.WriteLine(("Did LogonUser
succeed? " + success))
> Console.WriteLine(("Value of Windows NT
token: " +
>tokenHandle.ToString()))
>
> ' Check the identity.
> Console.WriteLine(("Before
impersonation: " +
>WindowsIdentity.GetCurrent().Name))
>
> Dim retVal As Boolean = DuplicateToken
(tokenHandle,
>SecurityImpersonation, dupeTokenHandle)
> If False = retVal Then
> CloseHandle(tokenHandle)
> Console.WriteLine("Exception thrown
in trying to
>duplicate token.")
> Return
> End If
>
> ' TThe token that is passed to the
following constructor
>must
> ' be a primary token in order to use it
for impersonation.
> Dim newId As New WindowsIdentity
(dupeTokenHandle)
> Dim impersonatedUser As
WindowsImpersonationContext =
>newId.Impersonate()
>
> ' Check the identity.
> Console.WriteLine(("After
impersonation: " +
>WindowsIdentity.GetCurrent().Name))
>
> ' Stop impersonating the user.
> impersonatedUser.Undo()
>
> ' Check the identity.
> Console.WriteLine(("After Undo: " +
>WindowsIdentity.GetCurrent().Name))
>
> ' Free the tokens.
> 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
> Catch ex As Exception
> Console.WriteLine(("Exception
occurred. " + ex.Message))
> End Try
> End Sub 'Main
> End Class 'Class1
>
>
>
>--
>This posting is provided "AS IS" with no warranties, and
confers no rights.
>Use of included script samples are subject to the terms
specified at
>http://www.microsoft.com/info/cpyright.htm
>
>
>"Chet Borg" <borgc@polarfab.com> wrote in message
>news:02a801c3554c$dd09fa80$a601280a@phx.gbl...
>> I am writing a application in VB.net which
automatically
>> updates applications on our network. I have everything
>> working except for registering updated dlls for the vb6
>> programs on Windows XP workstations (due to the
security
>> settings in Windows XP, non priv users are not allowed
to
>> register dlls) - according to our NT Admin. A colleague
>> suggested that I use Impersonation, to temporarily
>> imperonate a priv user.
>>
>> When I impersonate the user, the new username is
>> returned - however I do not gain the rights associated
>> with this new user. I was originally using the Win API
>> DuplicateToken() but switched to the DuplicateTokenEx
(),
>> after some research on the web.
>>
>> The code I use for the the function follows.
>> Any assistance would be appreciated.
>>
>>
>>
>> Public Function ImpersonateUserAndRegDLLs(ByVal
>> MyDLLs As c_DLLs) As String
>>
>> Dim sName As String
>> Dim token As New IntPtr(0)
>> Dim TokenCopy As New IntPtr(0)
>> Dim iLogResult As Integer
>> Dim newPrincipal As
>> System.Security.Principal.WindowsPrincipal
>> Const SecurityImpersonation As Integer =
>> System.Management.ImpersonationLevel.Impersonate
>> Dim DLL As c_DLL
>> Dim TokenAttributes As New SECURITY_ATTRIBUTES
>> Try
>> 'Logs On the User to the Domain
>> iLogResult = LogonUser(USERNAME,
>> Environment.UserDomainName, PWD, LOGON32_LOGON_NETWORK,
>> LOGON32_PROVIDER_WINNT50, token)
>>
>> 'Gets name of current user
>> sName =
>> System.Security.Principal.WindowsIdentity.GetCurrent
>> ().Name
>> 'Create a copy of the Token you are trying
to
>> impersonate
>> 'Dim retVal As Boolean = DuplicateToken
>> (token, SecurityImpersonation, TokenCopy)
>> Dim iDupResult As Integer =
DuplicateTokenEx
>> (token, MAXIMUM_ALLOWED, TokenAttributes,
>> SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation,
>> TOKEN_TYPE.TokenPrimary, TokenCopy)
>>
>> sName =
>> System.Security.Principal.WindowsIdentity.GetCurrent
>> ().Name
>>
>> 'Tests if DuplicateToken works
>> If iDupResult = 0 Or iLogResult = 0 Then
>> CloseHandle(token)
>> frm.lstFileHist.Items.Add("Error --
>> Logging on BuildXP")
>> Else
>> 'Creates a new Windows Identity
>> Dim NewId As New
>> System.Security.Principal.WindowsIdentity(TokenCopy)
>> 'Performs the impersonation
>> Dim ImpersonatedUser As
>> System.Security.Principal.WindowsImpersonationContext =
>> NewId.Impersonate
>>
>> 'Used to Chk impersonation worked
>> sName =
>> System.Security.Principal.WindowsIdentity.GetCurrent
>> ().Name
>>
>> 'Creates a Windows Principal based in
the
>> New Identity
>> 'Used to check if the Users privs were
>> impersonated also
>> newPrincipal = New
>> System.Security.Principal.WindowsPrincipal(NewId)
>>
>> 'Loops through all DLLs and Registers
Them
>> 'Regular User is not a member of
>> Group "Domain Admins", after the impersonation this
>> should be returned a true
>>
>> MessageBox.Show("The user is a member
of
>> Domain Admins: " & newPrincipal.IsInRole("Domain
>> Admins").ToString)
>> MessageBox.Show("User is " & sName)
>> MessageBox.Show("Token: " &
>> System.Security.Principal.WindowsIdentity.GetCurrent
>> ().Token.ToString)
>>
>> '** impersonation works, but the
>> impersonated user doesn't get any of the
>> '** rights of the user it is
>> impersonating, so it is unable to register the DLLs.
>>
>> For Each DLL In MyDLLs
>> frm.lstFileHist.Items.Add
("Attempting
>> to Register - " & DLL.FileName)
>> Dim sResult As String
>> 'Next Line uses the Shell function
to
>> execute a regsvr32 cmd
>> sResult = DLL.RegisterDLL()
>> If sResult = "TRUE" Then
>> frm.lstFileHist.Items.Add
>> ("Successfully Executed Regsvr32 for - " &
DLL.FileName)
>> Else
>> frm.lstFileHist.Items.Add
(sResult)
>> End If
>> Next
>>
>> 'Stop Impersonation
>> ImpersonatedUser.Undo()
>>
>> 'Used to Chk impersonation.undo worked
>> sName =
>> System.Security.Principal.WindowsIdentity.GetCurrent
>> ().Name
>> MessageBox.Show("User is " & sName)
>> MessageBox.Show("Token: " &
>> System.Security.Principal.WindowsIdentity.GetCurrent
>> ().Token.ToString)
>>
>> End If
>> Catch ex As Exception
>> MessageBox.Show(ex.ToString)
>> Finally
>> If Not System.IntPtr.op_Equality(token,
>> IntPtr.Zero) Then
>> CloseHandle(token)
>> End If
>> If Not System.IntPtr.op_Equality(TokenCopy,
>> IntPtr.Zero) Then
>> CloseHandle(TokenCopy)
>> End If
>> End Try
>> End Function
>
>
>.
>
- Next message: Ivan Medvedev [MS]: "Re: TripleDESCryptoServiceProvider vs. CryptoAPI"
- Previous message: Michel Gallant: "Re: How to get KeyUsage field given .NET X509Certificate instance?"
- In reply to: Shel Blauman [MSFT]: "Re: System.Security.Principal.WindowsImpersonation"
- Next in thread: Shel Blauman [MSFT]: "Re: System.Security.Principal.WindowsImpersonation"
- Reply: Shel Blauman [MSFT]: "Re: System.Security.Principal.WindowsImpersonation"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ] [ attachment ]
Relevant Pages
|