Imports System
Imports System.Threading
Imports System.Security
Imports System.Security.Permissions
Imports System.Security.Principal
Imports System.Runtime.InteropServices
Module Module1
Sub Main()
Try
Console.WriteLine("Executing the Main method in the primary thread.")
Dim fdp As New FileDialogPermission( _
FileDialogPermissionAccess.OpenSave)
fdp.Deny()
Dim sC As Security.SecurityContext
sC = Security.SecurityContext.Capture()
' Do not allow the security context to pass across threads;
' suppress its flow.
Dim aFC As AsyncFlowControl
aFC = Security.SecurityContext.SuppressFlow()
Dim t1 As New Thread(New ThreadStart(AddressOf DemandPermission))
t1.Start()
t1.Join()
Console.WriteLine("Is the flow suppressed? " & _
Security.SecurityContext.IsFlowSuppressed())
Console.WriteLine("Restore the flow.")
aFC.Undo()
Console.WriteLine("Is the flow suppressed? " & _
Security.SecurityContext.IsFlowSuppressed())
Dim t2 As New Thread(New ThreadStart(AddressOf DemandPermission))
t2.Start()
t2.Join()
CodeAccessPermission.RevertDeny()
Dim iU As New ImpersonateUser()
iU.Impersonate()
Dim t5 As New Thread(New ThreadStart(AddressOf CheckIdentity))
t5.Start()
t5.Join()
Console.WriteLine("Suppress the flow of the Windows identity.")
Dim aFC2 As AsyncFlowControl
aFC2 = Security.SecurityContext.SuppressFlowWindowsIdentity()
Console.WriteLine("Has the Windows identity flow been suppressed? " & _
Security.SecurityContext.IsWindowsIdentityFlowSuppressed())
Dim t6 As New Thread(New ThreadStart(AddressOf CheckIdentity))
Console.WriteLine("Starting the second thread.")
t6.Start()
t6.Join()
Console.WriteLine("Returned from the second thread.")
' Restore the flow of the Windows identity for the impersonated
' user.
aFC2.Undo()
WriteLine("User name after restoring the Windows identity flow: ")
WriteLine(WindowsIdentity.GetCurrent().Name)
Console.WriteLine("Undo the impersonation.")
iU.Undo()
Catch ex As Exception
WriteLine(ex.Message)
End Try
' Align interface and conclude application.
WriteLine(vbCrLf + "This sample completed successfully;" + _
" press Exit to continue.")
End Sub
' Test method to be called on a second thread.
Sub DemandPermission()
Try
Console.WriteLine("Executing the DemandPermission method from a" & _
"seperate thread")
Dim fDP As New FileDialogPermission( _
FileDialogPermissionAccess.OpenSave)
fDP.Demand()
Console.WriteLine("FileDialogPermission was successsfully demanded.")
Catch e As Exception
Console.WriteLine(e.Message)
End Try
End Sub
Sub CheckIdentity()
Console.WriteLine("Current user: " & WindowsIdentity.GetCurrent().Name)
End Sub
Public Class ImpersonateUser
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
Declare Auto Function CloseHandle Lib "kernel32.dll" ( _
ByVal handle As IntPtr) As Boolean
Declare Auto Function DuplicateToken Lib "advapi32.dll" ( _
ByVal ExistingTokenHandle As IntPtr, _
ByVal SECURITY_IMPERSONATION_LEVEL As Integer, _
ByRef DuplicateTokenHandle As IntPtr) As Boolean
Private Shared tokenHandle As New IntPtr(0)
Private Shared dupeTokenHandle As New IntPtr(0)
Private Shared impersonatedUser As WindowsImpersonationContext
' If you incorporate this code into a DLL,
' be sure to demand that it runs with FullTrust.
<PermissionSetAttribute(SecurityAction.Demand, Name:="FullTrust")> _
Public Sub Impersonate()
Try
Dim userName, domainName As String
' Use the unmanaged LogonUser function to get the user token for
' the specified user, domain, and password.
' To impersonate a user on this machine, use the local machine
' name for the domain name.
domainName = InputBox("Enter the name of the domain to log on to")
userName = InputBox("Enter the logon name of the user that " + _
"you wish to impersonate on " + domainName)
Const LOGON32_PROVIDER_DEFAULT As Integer = 0
' Passing this parameter causes LogonUser to create a primary
' token.
Const LOGON32_LOGON_INTERACTIVE As Integer = 2
tokenHandle = IntPtr.Zero
' Call LogonUser to obtain a handle to an access token.
Dim returnValue As Boolean = LogonUser( _
userName, _
domainName, _
InputBox("Enter the password for " + userName), _
LOGON32_LOGON_INTERACTIVE, _
LOGON32_PROVIDER_DEFAULT, _
tokenHandle)
If (returnValue) Then
Dim outputMessage As String
outputMessage = ("User successfully logged on!" + vbCrLf)
outputMessage += ("Windows NT token value: ")
outputMessage += (tokenHandle.ToString() + vbCrLf)
outputMessage += ("User name before impersonation: ")
outputMessage += (WindowsIdentity.GetCurrent().Name + vbCrLf)
Dim newId As New WindowsIdentity(tokenHandle)
impersonatedUser = newId.Impersonate()
outputMessage += ("User name after the impersonation: ")
outputMessage += (WindowsIdentity.GetCurrent().Name + vbCrLf)
MsgBox(outputMessage)
Else
Dim ret As Integer = Marshal.GetLastWin32Error()
Throw New System.ComponentModel.Win32Exception(ret)
End If
Catch ex As Exception
MsgBox("LogonUser call failed Exception occurred. " & ex.Message)
End Try
End Sub
Public Sub Undo()
impersonatedUser.Undo()
' Check the identity.
MsgBox("User name restored to : " + _
WindowsIdentity.GetCurrent().Name)
' Free the tokens.
If tokenHandle <> IntPtr.Zero Then
CloseHandle(tokenHandle)
End If
End Sub
End Class
End Module
using System;
using System.Threading;
using System.Security;
using System.Security.Permissions;
using System.Security.Principal;
using System.Runtime.InteropServices;
class SecurityContextSample
{
static void Main()
{
try
{
Console.WriteLine("Executing the Main method in the primary " +
"thread.");
FileDialogPermission fdp = new FileDialogPermission(
FileDialogPermissionAccess.OpenSave);
fdp.Deny();
// Do not allow the security context to pass across threads;
// suppress its flow.
AsyncFlowControl aFC = SecurityContext.SuppressFlow();
Thread t1 = new Thread(new ThreadStart(DemandPermission));
t1.Start();
t1.Join();
Console.WriteLine("Is the flow suppressed? " +
SecurityContext.IsFlowSuppressed());
Console.WriteLine("Restore the flow.");
aFC.Undo();
Console.WriteLine("Is the flow suppressed? " +
SecurityContext.IsFlowSuppressed());
Thread t2 = new Thread(new ThreadStart(DemandPermission));
t2.Start();
t2.Join();
CodeAccessPermission.RevertDeny();
// Show the Deny is no longer present.
Thread t3 = new Thread(new ThreadStart(DemandPermission));
t3.Start();
t3.Join();
ImpersonateUser iU = new ImpersonateUser();
iU.Impersonate();
Thread t5 = new Thread(new ThreadStart(CheckIdentity));
t5.Start();
t5.Join();
Console.WriteLine("Suppress the flow of the Windows identity.");
AsyncFlowControl aFC2 =
SecurityContext.SuppressFlowWindowsIdentity();
Console.WriteLine("Has the Windows identity flow been suppressed?"
+ SecurityContext.IsWindowsIdentityFlowSuppressed());
Thread t6 = new Thread(new ThreadStart(CheckIdentity));
t6.Start();
t6.Join();
// Restore the flow of the Windows identity for the impersonated
// user.
aFC2.Undo();
Console.WriteLine("User name after restoring the Windows identity"
+ " flow with Undo: \n" + WindowsIdentity.GetCurrent().Name);
iU.Undo();
Console.WriteLine("This sample completed successfully;" +
" press Enter to exit.");
Console.Read();
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
// Test method to be called on a second thread.
static void DemandPermission()
{
try
{
Console.WriteLine("This is the thread executing the " +
"DemandPermission method.");
new FileDialogPermission(
FileDialogPermissionAccess.OpenSave).Demand();
Console.WriteLine("FileDialogPermission was successsfully" +
" demanded.");
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
static void CheckIdentity()
{
Console.WriteLine("Current user: " +
WindowsIdentity.GetCurrent().Name);
}
}
// Perform user impersonation.
public class ImpersonateUser
{
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(
String lpszUsername,
String lpszDomain,
String lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(
IntPtr ExistingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL,
ref IntPtr DuplicateTokenHandle);
private static IntPtr tokenHandle = new IntPtr(0);
private static IntPtr dupeTokenHandle = new IntPtr(0);
private static WindowsImpersonationContext impersonatedUser;
// If you incorporate this code into a DLL, be sure to demand that it
// runs with FullTrust.
[PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
public void Impersonate()
{
try
{
string userName, domainName;
// Use the unmanaged LogonUser function to get the user token for
// the specified user, domain, and password.
// To impersonate a user on this machine, use the local machine
// name for the domain name.
Console.Write("Enter the name of the domain to log on to: ");
domainName = Console.ReadLine();
Console.Write("Enter the logon name of the user that you wish to"
+ " impersonate on {0}: ", domainName);
userName = Console.ReadLine();
Console.Write("Enter the password for {0}: ", userName);
const int LOGON32_PROVIDER_DEFAULT = 0;
// Passing this parameter causes LogonUser to create a primary
// token.
const int LOGON32_LOGON_INTERACTIVE = 2;
tokenHandle = IntPtr.Zero;
// Call LogonUser to obtain a handle to an access token.
bool returnValue = LogonUser(
userName,
domainName,
Console.ReadLine(),
LOGON32_LOGON_INTERACTIVE,
LOGON32_PROVIDER_DEFAULT,
ref tokenHandle);
Console.WriteLine("LogonUser has been called.");
if (false == returnValue)
{
int ret = Marshal.GetLastWin32Error();
Console.WriteLine("LogonUser call failed with error code : " +
ret);
throw new System.ComponentModel.Win32Exception(ret);
}
Console.WriteLine("Did LogonUser succeed? " +
(returnValue ? "Yes" : "No"));
Console.WriteLine("Value of the Windows NT token: " +
tokenHandle);
// Check the identity.
Console.WriteLine("User name before the impersonation: " +
WindowsIdentity.GetCurrent().Name);
WindowsIdentity newId = new WindowsIdentity(tokenHandle);
impersonatedUser = newId.Impersonate();
// Check the identity.
Console.WriteLine("User name after the impersonation: " +
WindowsIdentity.GetCurrent().Name);
}
catch (Exception ex)
{
Console.WriteLine("Exception occurred. " + ex.Message);
}
}
public void Undo()
{
impersonatedUser.Undo();
// Check the identity.
Console.WriteLine("After Undo: " + WindowsIdentity.GetCurrent().Name);
// Free the tokens.
if (tokenHandle != IntPtr.Zero)
CloseHandle(tokenHandle);
}
}