- // 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.
- // The sample is intended to be executed in a .NET Framework 1.1 environment. To execute
- // this code in a 1.0 environment you will need to use a duplicate token in the call to the
- // WindowsIdentity constructor. See KB article Q319615 for more information.
-
- using System;
- using System.Runtime.InteropServices;
- using System.Security.Principal;
- using System.Security.Permissions;
-
- [assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode = true)]
- [assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")]
- public class ImpersonationDemo
- {
- const int LOGON32_LOGON_INTERACTIVE = 2;
- const int LOGON32_LOGON_NETWORK = 3;
- const int LOGON32_LOGON_BATCH = 4;
- const int LOGON32_LOGON_SERVICE = 5;
- const int LOGON32_LOGON_UNLOCK = 7;
- const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
- const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
-
- const int LOGON32_PROVIDER_DEFAULT = 0;
- const int LOGON32_PROVIDER_WINNT50 = 3;
- const int LOGON32_PROVIDER_WINNT40 = 2;
- const int LOGON32_PROVIDER_WINNT35 = 1;
-
- [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 = System.Runtime.InteropServices.CharSet.Auto)]
- //private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource,
- // int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* Arguments);
-
- [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);
-
- // Test harness.
- // If you incorporate this code into a DLL, be sure to demand FullTrust.
- [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
- public static void Main2(string[] args)
- {
- IntPtr tokenHandle = new IntPtr(0);
- IntPtr dupeTokenHandle = new IntPtr(0);
- try
- {
- string userName, domainName;
- // 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 the 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);
-
- tokenHandle = IntPtr.Zero;
-
- // Call LogonUser to obtain a handle to an access token.
- bool returnValue = LogonUser(userName, domainName, Console.ReadLine(),
- LOGON32_LOGON_NEW_CREDENTIALS, LOGON32_PROVIDER_DEFAULT,
- ref tokenHandle);
-
- Console.WriteLine("LogonUser called.");
-
- if (false == returnValue)
- {
- int ret = Marshal.GetLastWin32Error();
- Console.WriteLine("LogonUser failed with error code : {0}", ret);
- throw new System.ComponentModel.Win32Exception(ret);
- }
-
- Console.WriteLine("Did LogonUser Succeed? " + (returnValue ? "Yes" : "No"));
- Console.WriteLine("Value of Windows NT token: " + tokenHandle);
-
- // Check the identity.
- Console.WriteLine("Before impersonation: "
- + WindowsIdentity.GetCurrent().Name);
- // Use the token handle returned by LogonUser.
- WindowsIdentity newId = new WindowsIdentity(tokenHandle);
- WindowsImpersonationContext impersonatedUser = 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 (tokenHandle != IntPtr.Zero)
- CloseHandle(tokenHandle);
-
- }
- catch (Exception ex)
- {
- Console.WriteLine("Exception occurred. " + ex.Message);
- }
-
- Console.Read();
- }
-
- }
or
- public class ImpersonateIdentity : IDisposable
- {
- [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
- public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
-
- [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
- public extern static bool CloseHandle(IntPtr handle);
-
- [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
- public static ImpersonateIdentity Impersonate(string userName, string password, string domainName)
- {
- ImpersonateIdentity identity = new ImpersonateIdentity();
-
- const int LOGON32_PROVIDER_DEFAULT = 0;
- //This parameter causes LogonUser to create a primary token.
- const int LOGON32_LOGON_INTERACTIVE = 2;
-
- // Call LogonUser to obtain a handle to an access token.
- bool returnValue = LogonUser(userName, domainName, password,
- LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
- out identity.safeTokenHandle);
-
- if (false == returnValue)
- {
- int ret = Marshal.GetLastWin32Error();
- throw new System.ComponentModel.Win32Exception(ret);
- }
-
- identity.impersonatedUser = WindowsIdentity.Impersonate(identity.safeTokenHandle.DangerousGetHandle());
- return identity;
- }
-
- WindowsImpersonationContext impersonatedUser;
- SafeTokenHandle safeTokenHandle;
-
- private ImpersonateIdentity() { }
-
- public void Dispose()
- {
- if (impersonatedUser != null) impersonatedUser.Dispose();
- if (safeTokenHandle != null) safeTokenHandle.Dispose();
- }
- }
-
- public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
- {
- private SafeTokenHandle()
- : base(true)
- {
- }
-
- [DllImport("kernel32.dll")]
- [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [SuppressUnmanagedCodeSecurity]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool CloseHandle(IntPtr handle);
-
- protected override bool ReleaseHandle()
- {
- return CloseHandle(handle);
- }
- }
reference :
or
- using System;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Security.Principal;
- using System.Security.Permissions;
-
- [assembly: SecurityPermissionAttribute(SecurityAction.RequestMinimum, UnmanagedCode = true)]
- [assembly: PermissionSetAttribute(SecurityAction.RequestMinimum, Name = "FullTrust")]
- namespace ConsoleApplication1
- {
- class Class1
- {
- //登入
- [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")]
- public extern static bool CloseHandle(IntPtr hToken);
-
- public Class1()
- {
- string UserName = "username";
- string MachineName = "192.168.0.10";
- string Pw = "password";
- string IPath = @"\\" + MachineName + @"\shared";
-
- const int LOGON32_PROVIDER_DEFAULT = 0;
- const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
-
- IntPtr tokenHandle = new IntPtr(0);
- tokenHandle = IntPtr.Zero;
-
- //將登入的Token放在tokenHandle
- bool returnValue = LogonUser(
- UserName,
- MachineName,
- Pw,
- LOGON32_LOGON_NEW_CREDENTIALS,
- LOGON32_PROVIDER_DEFAULT,
- ref tokenHandle
- );
-
- //讓程式模擬登入的使用者
- WindowsIdentity w = new WindowsIdentity(tokenHandle);
- w.Impersonate();
- if (false == returnValue)
- {
- //登入失敗的處理
- return;
- }
- //取得該目錄下的所有檔案名稱
- DirectoryInfo dir = new DirectoryInfo(IPath);
- FileInfo[] inf = dir.GetFiles();
- for (int i = 0; i < inf.Length; i++)
- {
- Console.WriteLine(inf[i].Name);
- }
- }
- }
- }
Condition : in a domain
- LogonUser(
- UserName,
- "myDomain",
- Pw,LOGON32_LOGON_NEW_CREDENTIALS,
- LOGON32_PROVIDER_DEFAULT,
- ref tokenHandle
- );
reference :
[C#]在程式中模擬特定的windows帳號存取網路芳鄰