Re: System.Security.Principal.WindowsImpersonation

From: Chet Borg (borgc_at_polarfab.com)
Date: 07/29/03

  • Next message: Shawn Farkas [MS]: "Re: .Net scurity drives me nuts"
    Date: Tue, 29 Jul 2003 14:15:23 -0700
    
    

    Thanks Shel,

     I ended up calling Microsoft on this. It turns out, that
    since I was using the Shell() function to launch regsvr32
    the command was taking the privs of the original user.
    They suggest that I use the API (Unmanaged Code)

    Private Declare Function CreateProcess
    Lib "kernel32.dll" Alias "CreateProcessA"

    Which worked fine. :)

    The following was another error I had.

    This line came back false, because I needed to have the
    DomainName and the Group.

    MessageBox.Show("The user is a member of
    Domain Admins: " & newPrincipal.IsInRole("Domain
    Admins").ToString)<-- Returns: FALSE
     
    So it should have looked like this:

    MessageBox.Show("The user is a member of
    Domain Admins: " & newPrincipal.IsInRole("MyDomain\Domain
    Admins").ToString) <-- Returns: TRUE

    So, in short the code did work, I just was trying to do
    something with impersonation that wasn't allowed.

    Thanks again - Hopefully this helps some on else.

    >-----Original Message-----
    >I'll research this and get back to you.
    >
    >Shel
    >
    >--
    >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
    >
    >
    >"borgc" <borgc@polarfab.com> wrote in message
    >news:3d3d01c355d9$dac5b4c0$a001280a@phx.gbl...
    >> 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: Shawn Farkas [MS]: "Re: .Net scurity drives me nuts"

    Relevant Pages

    • RE: check if user belong to a domain against active directory without
      ... "Any one who has never made a mistake has never tried anything new" - Einstein ... > I just get stuck on how to check if a user is a member of network. ... > is a member of the domain account against Global Catalog. ... Changing WindonIdentity with impersonation at run time is ...
      (microsoft.public.dotnet.framework.aspnet)
    • Web Part referencing other assemblies throws security exception
      ... member of, who are the members of this group on that server etc.). ... It seems the impersonation code doesn't event run, and a security exception ... and therefore the security exception is thrown even before the code gets to ... how can I allow this impersonation to take place? ...
      (microsoft.public.sharepoint.portalserver.development)
    • check if user belong to a domain against active directory without impersonation
      ... I just get stuck on how to check if a user is a member of network. ... I am building an internal tracking system with ASP.Net with Form ... Changing WindonIdentity with impersonation at run time is ...
      (microsoft.public.dotnet.framework.aspnet)
    • Re: Identity Impersonation question.
      ... individual webs (I know you mentioned you dont want to allow singular webs ... If the users are not a member of a domain, then setup ... all I need to do then is to find a way to prevent impersonation ...
      (microsoft.public.dotnet.framework.aspnet)