public TokenProvider GetLinkedToken(uint desiredAccess = MAXIMUM_ALLOWED) { // Now we allocate a buffer for the integrity level information. int cb = Marshal.SizeOf <TOKEN_LINKED_TOKEN>(); var pLinkedToken = Marshal.AllocHGlobal(cb); if (pLinkedToken == IntPtr.Zero) { throw new Win32Exception(); } try { // Now we ask for the integrity level information again. This may fail // if an administrator has added this account to an additional group // between our first call to GetTokenInformation and this one. if (!TokensApi.GetTokenInformation(Token.DangerousGetHandle(), TokensApi.TOKEN_INFORMATION_CLASS.TokenLinkedToken, pLinkedToken, cb, out cb)) { throw new Win32Exception(); } // Marshal the TOKEN_MANDATORY_LABEL struct from native to .NET object. TOKEN_LINKED_TOKEN linkedTokenStruct = (TOKEN_LINKED_TOKEN) Marshal.PtrToStructure(pLinkedToken, typeof(TOKEN_LINKED_TOKEN)); var sa = new SECURITY_ATTRIBUTES(); sa.nLength = 0; SafeTokenHandle newToken; if (!TokensApi.DuplicateTokenEx(linkedTokenStruct.LinkedToken, desiredAccess, IntPtr.Zero, SECURITY_IMPERSONATION_LEVEL.SecurityImpersonation, TOKEN_TYPE.TokenPrimary, out newToken)) { throw new Win32Exception(); } CloseHandle(linkedTokenStruct.LinkedToken); this.Token.Close(); this.Token = newToken; } finally { Marshal.FreeHGlobal(pLinkedToken); } return(this); }
static internal int GetProcessIntegrityLevel(IntPtr processHandle) { /* * https://docs.microsoft.com/en-us/previous-versions/dotnet/articles/bb625963(v=msdn.10)?redirectedfrom=MSDN * https://support.microsoft.com/en-us/help/243330/well-known-security-identifiers-in-windows-operating-systems * S-1-16-0 Untrusted Mandatory Level An untrusted integrity level. * S-1-16-4096 Low Mandatory Level A low integrity level. * S-1-16-8192 Medium Mandatory Level A medium integrity level. * S-1-16-8448 Medium Plus Mandatory Level A medium plus integrity level. * S-1-16-12288 High Mandatory Level A high integrity level. * S-1-16-16384 System Mandatory Level A system integrity level. * S-1-16-20480 Protected Process Mandatory Level A protected-process integrity level. * S-1-16-28672 Secure Process Mandatory Level A secure process integrity level. */ int IL = -1; //SafeWaitHandle hToken = null; IntPtr hToken = IntPtr.Zero; int cbTokenIL = 0; IntPtr pTokenIL = IntPtr.Zero; try { // Open the access token of the current process with TOKEN_QUERY. if (!OpenProcessToken(processHandle, Native.TokensApi.TOKEN_QUERY, out hToken)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Then we must query the size of the integrity level information // associated with the token. Note that we expect GetTokenInformation // to return false with the ERROR_INSUFFICIENT_BUFFER error code // because we've given it a null buffer. On exit cbTokenIL will tell // the size of the group information. if (!Native.TokensApi.GetTokenInformation(hToken, Native.TokensApi.TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, IntPtr.Zero, 0, out cbTokenIL)) { int error = Marshal.GetLastWin32Error(); const int ERROR_INSUFFICIENT_BUFFER = 0x7a; if (error != ERROR_INSUFFICIENT_BUFFER) { // When the process is run on operating systems prior to // Windows Vista, GetTokenInformation returns false with the // ERROR_INVALID_PARAMETER error code because // TokenIntegrityLevel is not supported on those OS's. throw new Win32Exception(error); } } // Now we allocate a buffer for the integrity level information. pTokenIL = Marshal.AllocHGlobal(cbTokenIL); if (pTokenIL == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Now we ask for the integrity level information again. This may fail // if an administrator has added this account to an additional group // between our first call to GetTokenInformation and this one. if (!TokensApi.GetTokenInformation(hToken, TokensApi.TOKEN_INFORMATION_CLASS.TokenIntegrityLevel, pTokenIL, cbTokenIL, out cbTokenIL)) { throw new Win32Exception(Marshal.GetLastWin32Error()); } // Marshal the TOKEN_MANDATORY_LABEL struct from native to .NET object. TokensApi.TOKEN_MANDATORY_LABEL tokenIL = (TokensApi.TOKEN_MANDATORY_LABEL) Marshal.PtrToStructure(pTokenIL, typeof(TokensApi.TOKEN_MANDATORY_LABEL)); IntPtr pIL = TokensApi.GetSidSubAuthority(tokenIL.Label.Sid, 0); IL = Marshal.ReadInt32(pIL); } finally { // Centralized cleanup for all allocated resources. Clean up only // those which were allocated, and clean them up in the right order. if (hToken != IntPtr.Zero) { CloseHandle(hToken); // Marshal.FreeHGlobal(hToken); // hToken.Close(); // hToken = null; } if (pTokenIL != IntPtr.Zero) { Marshal.FreeHGlobal(pTokenIL); pTokenIL = IntPtr.Zero; cbTokenIL = 0; } } return((_cacheGetCurrentIntegrityLevelCache = IL).Value); }