using System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; using System.Security; namespace ZeroLevel.Services.Impersonation { [SuppressUnmanagedCodeSecurity()] public static class ImpersonationNativeMethods { #region P/Invoke enums /// /// Authorization provider /// public enum LogonProvider : int { /// /// Use the standard logon provider for the system. /// The default security provider is negotiate, unless you pass NULL for the domain name and the user name /// is not in UPN format. In this case, the default provider is NTLM. /// NOTE: Windows 2000/NT: The default security provider is NTLM. /// LOGON32_PROVIDER_DEFAULT = 0, } /// /// Authorization method /// public enum LogonType : int { /// /// 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. /// LOGON32_LOGON_INTERACTIVE = 2, /// /// This logon type is intended for high performance servers to authenticate plaintext passwords. /// The LogonUser function does not cache credentials for this logon type. /// LOGON32_LOGON_NETWORK = 3, /// /// 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. /// LOGON32_LOGON_BATCH = 4, /// /// Indicates a service-type logon. The account provided must have the service privilege enabled. /// LOGON32_LOGON_SERVICE = 5, /// /// 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. /// LOGON32_LOGON_UNLOCK = 7, /// /// 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. /// LOGON32_LOGON_NETWORK_CLEARTEXT = 8, /// /// 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. /// LOGON32_LOGON_NEW_CREDENTIALS = 9, } /// /// Desired access level to token /// public struct TokenDesiredAccess { public static uint STANDARD_RIGHTS_REQUIRED = 0x000F0000; public static uint STANDARD_RIGHTS_READ = 0x00020000; public static uint TOKEN_ASSIGN_PRIMARY = 0x0001; /// /// Allows to create a copy /// public static uint TOKEN_DUPLICATE = 0x0002; public static uint TOKEN_IMPERSONATE = 0x0004; public static uint TOKEN_QUERY = 0x0008; public static uint TOKEN_QUERY_SOURCE = 0x0010; public static uint TOKEN_ADJUST_PRIVILEGES = 0x0020; public static uint TOKEN_ADJUST_GROUPS = 0x0040; public static uint TOKEN_ADJUST_DEFAULT = 0x0080; public static uint TOKEN_ADJUST_SESSIONID = 0x0100; public static uint TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY); public static uint TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT | TOKEN_ADJUST_SESSIONID); } /// /// The security type is used during the token duplication operation (in the current task) /// public enum SecurityImpersonationLevel : int { /// /// The server process cannot obtain identification information about the client, /// and it cannot impersonate the client. It is defined with no value given, and thus, /// by ANSI C rules, defaults to a value of zero. /// SecurityAnonymous = 0, /// /// The server process can obtain information about the client, such as security identifiers and privileges, /// but it cannot impersonate the client. This is useful for servers that export their own objects, /// for example, database products that export tables and views. /// Using the retrieved client-security information, the server can make access-validation decisions without /// being able to use other services that are using the client's security context. /// SecurityIdentification = 1, /// /// The server process can impersonate the client's security context on its local system. /// The server cannot impersonate the client on remote systems. /// SecurityImpersonation = 2, /// /// The server process can impersonate the client's security context on remote systems. /// NOTE: Windows NT: This impersonation level is not supported. /// SecurityDelegation = 3, } #endregion P/Invoke enums #region P/Invoke /// /// Authorization on behalf of the specified user /// /// Username /// Domain /// Password /// Authorization Type /// Provider (always 0) /// Token - login result /// [DllImport("advapi32.dll")] internal static extern int LogonUserA(String lpszUserName, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out MySafeTokenHandle phToken); /// /// Creating a duplicate token /// /// Original token /// /// /// [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] internal static extern int DuplicateToken(MySafeTokenHandle hToken, int impersonationLevel, out MySafeTokenHandle hNewToken); [DllImport("kernel32.dll", CharSet = CharSet.Auto)] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)] internal static extern bool CloseHandle(IntPtr handle); /// /// Attempt to get a token running process /// /// Process pointer /// /// Token - result /// [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out MySafeTokenHandle TokenHandle); #endregion P/Invoke } }