internal static SidType ClassifySID(IntPtr pSid) { Debug.Assert(UnsafeNativeMethods.IsValidSid(pSid)); // Get the issuing authority and the first RID IntPtr pIdentAuth = UnsafeNativeMethods.GetSidIdentifierAuthority(pSid); UnsafeNativeMethods.SID_IDENTIFIER_AUTHORITY identAuth = (UnsafeNativeMethods.SID_IDENTIFIER_AUTHORITY)Marshal.PtrToStructure(pIdentAuth, typeof(UnsafeNativeMethods.SID_IDENTIFIER_AUTHORITY)); IntPtr pRid = UnsafeNativeMethods.GetSidSubAuthority(pSid, 0); int rid = Marshal.ReadInt32(pRid); // These bit signify that the sid was issued by ADAM. If so then it can't be a fake sid. if ((identAuth.b3 & 0xF0) == 0x10) { return(SidType.RealObject); } // Is it S-1-5-...? if (!(identAuth.b1 == 0) && (identAuth.b2 == 0) && (identAuth.b3 == 0) && (identAuth.b4 == 0) && (identAuth.b5 == 0) && (identAuth.b6 == 5)) { // No, so it can't be a account or builtin SID. // Probably something like \Everyone or \LOCAL. return(SidType.FakeObject); } switch (rid) { case 21: // Account SID return(SidType.RealObject); case 32: // BUILTIN SID return(SidType.RealObjectFakeDomain); default: return(SidType.FakeObject); } }
internal static IntPtr GetMachineDomainSid() { IntPtr pPolicyHandle = IntPtr.Zero; IntPtr pBuffer = IntPtr.Zero; IntPtr pOA = IntPtr.Zero; try { UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES oa = new UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES(); pOA = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES))); Marshal.StructureToPtr(oa, pOA, false); int err = UnsafeNativeMethods.LsaOpenPolicy( IntPtr.Zero, pOA, 1, // POLICY_VIEW_LOCAL_INFORMATION ref pPolicyHandle); if (err != 0) { GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "GetMachineDomainSid: LsaOpenPolicy failed, gle=" + SafeNativeMethods.LsaNtStatusToWinError(err)); throw new PrincipalOperationException(String.Format(CultureInfo.CurrentCulture, StringResources.UnableToRetrievePolicy, SafeNativeMethods.LsaNtStatusToWinError(err))); } Debug.Assert(pPolicyHandle != IntPtr.Zero); err = UnsafeNativeMethods.LsaQueryInformationPolicy( pPolicyHandle, 5, // PolicyAccountDomainInformation ref pBuffer); if (err != 0) { GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "GetMachineDomainSid: LsaQueryInformationPolicy failed, gle=" + SafeNativeMethods.LsaNtStatusToWinError(err)); throw new PrincipalOperationException(String.Format(CultureInfo.CurrentCulture, StringResources.UnableToRetrievePolicy, SafeNativeMethods.LsaNtStatusToWinError(err))); } Debug.Assert(pBuffer != IntPtr.Zero); UnsafeNativeMethods.POLICY_ACCOUNT_DOMAIN_INFO info = (UnsafeNativeMethods.POLICY_ACCOUNT_DOMAIN_INFO) Marshal.PtrToStructure(pBuffer, typeof(UnsafeNativeMethods.POLICY_ACCOUNT_DOMAIN_INFO)); Debug.Assert(UnsafeNativeMethods.IsValidSid(info.domainSid)); // Now we make a copy of the SID to return int sidLength = UnsafeNativeMethods.GetLengthSid(info.domainSid); IntPtr pCopyOfSid = Marshal.AllocHGlobal(sidLength); bool success = UnsafeNativeMethods.CopySid(sidLength, pCopyOfSid, info.domainSid); if (!success) { int lastError = Marshal.GetLastWin32Error(); GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "GetMachineDomainSid: CopySid failed, errorcode=" + lastError); throw new PrincipalOperationException( String.Format(CultureInfo.CurrentCulture, StringResources.UnableToRetrievePolicy, lastError)); } return(pCopyOfSid); } finally { if (pPolicyHandle != IntPtr.Zero) { UnsafeNativeMethods.LsaClose(pPolicyHandle); } if (pBuffer != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(pBuffer); } if (pOA != IntPtr.Zero) { Marshal.FreeHGlobal(pOA); } } }
internal static IntPtr GetCurrentUserSid() { IntPtr pTokenHandle = IntPtr.Zero; IntPtr pBuffer = IntPtr.Zero; try { // // Get the current user's SID // int error = 0; // Get the current thread's token if (!UnsafeNativeMethods.OpenThreadToken( UnsafeNativeMethods.GetCurrentThread(), 0x8, // TOKEN_QUERY true, ref pTokenHandle )) { if ((error = Marshal.GetLastWin32Error()) == 1008) // ERROR_NO_TOKEN { Debug.Assert(pTokenHandle == IntPtr.Zero); // Current thread doesn't have a token, try the process if (!UnsafeNativeMethods.OpenProcessToken( UnsafeNativeMethods.GetCurrentProcess(), 0x8, // TOKEN_QUERY ref pTokenHandle )) { int lastError = Marshal.GetLastWin32Error(); GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "GetCurrentUserSid: OpenProcessToken failed, gle=" + lastError); throw new PrincipalOperationException( String.Format(CultureInfo.CurrentCulture, StringResources.UnableToOpenToken, lastError)); } } else { GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "GetCurrentUserSid: OpenThreadToken failed, gle=" + error); throw new PrincipalOperationException( String.Format(CultureInfo.CurrentCulture, StringResources.UnableToOpenToken, error)); } } Debug.Assert(pTokenHandle != IntPtr.Zero); int neededBufferSize = 0; // Retrieve the user info from the current thread's token // First, determine how big a buffer we need. bool success = UnsafeNativeMethods.GetTokenInformation( pTokenHandle, 1, // TokenUser IntPtr.Zero, 0, ref neededBufferSize); int getTokenInfoError = 0; if ((getTokenInfoError = Marshal.GetLastWin32Error()) != 122) // ERROR_INSUFFICIENT_BUFFER { GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "GetCurrentUserSid: GetTokenInformation (1st try) failed, gle=" + getTokenInfoError); throw new PrincipalOperationException( String.Format(CultureInfo.CurrentCulture, StringResources.UnableToRetrieveTokenInfo, getTokenInfoError)); } // Allocate the necessary buffer. Debug.Assert(neededBufferSize > 0); pBuffer = Marshal.AllocHGlobal(neededBufferSize); // Load the user info into the buffer success = UnsafeNativeMethods.GetTokenInformation( pTokenHandle, 1, // TokenUser pBuffer, neededBufferSize, ref neededBufferSize); if (!success) { int lastError = Marshal.GetLastWin32Error(); GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "GetCurrentUserSid: GetTokenInformation (2nd try) failed, neededBufferSize=" + neededBufferSize + ", gle=" + lastError); throw new PrincipalOperationException( String.Format(CultureInfo.CurrentCulture, StringResources.UnableToRetrieveTokenInfo, lastError)); } // Retrieve the user's SID from the user info UnsafeNativeMethods.TOKEN_USER tokenUser = (UnsafeNativeMethods.TOKEN_USER)Marshal.PtrToStructure(pBuffer, typeof(UnsafeNativeMethods.TOKEN_USER)); IntPtr pUserSid = tokenUser.sidAndAttributes.pSid; // this is a reference into the NATIVE memory (into pBuffer) Debug.Assert(UnsafeNativeMethods.IsValidSid(pUserSid)); // Now we make a copy of the SID to return int userSidLength = UnsafeNativeMethods.GetLengthSid(pUserSid); IntPtr pCopyOfUserSid = Marshal.AllocHGlobal(userSidLength); success = UnsafeNativeMethods.CopySid(userSidLength, pCopyOfUserSid, pUserSid); if (!success) { int lastError = Marshal.GetLastWin32Error(); GlobalDebug.WriteLineIf(GlobalDebug.Error, "Utils", "GetCurrentUserSid: CopySid failed, errorcode=" + lastError); throw new PrincipalOperationException( String.Format(CultureInfo.CurrentCulture, StringResources.UnableToRetrieveTokenInfo, lastError)); } return(pCopyOfUserSid); } finally { if (pTokenHandle != IntPtr.Zero) { UnsafeNativeMethods.CloseHandle(pTokenHandle); } if (pBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(pBuffer); } } }