internal AuthZSet( byte[] userSid, NetCred credentials, ContextOptions contextOptions, string flatUserAuthority, StoreCtx userStoreCtx, object userCtxBase) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "AuthZSet: SID={0}, authority={1}, storeCtx={2}", Utils.ByteArrayToString(userSid), flatUserAuthority, userStoreCtx.GetType()); _userType = userStoreCtx.OwningContext.ContextType; _userCtxBase = userCtxBase; _userStoreCtx = userStoreCtx; _credentials = credentials; _contextOptions = contextOptions; // flatUserAuthority is flat domain name if userType == Domain, // flat host name if userType == LocalMachine _flatUserAuthority = flatUserAuthority; // Preload the PrincipalContext cache with the user's PrincipalContext _contexts[flatUserAuthority] = userStoreCtx.OwningContext; IntPtr hUser = IntPtr.Zero; // // Get the SIDs of the groups to which the user belongs // IntPtr pClientContext = IntPtr.Zero; IntPtr pResManager = IntPtr.Zero; IntPtr pBuffer = IntPtr.Zero; try { UnsafeNativeMethods.LUID luid = new UnsafeNativeMethods.LUID(); luid.low = 0; luid.high = 0; _psMachineSid = new SafeMemoryPtr(Utils.GetMachineDomainSid()); _psUserSid = new SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid)); bool f; int lastError = 0; GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Initializing resource manager"); // Create a resource manager f = UnsafeNativeMethods.AuthzInitializeResourceManager( UnsafeNativeMethods.AUTHZ_RM_FLAG.AUTHZ_RM_FLAG_NO_AUDIT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out pResManager ); if (f) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting ctx from SID"); // Construct a context for the user based on the user's SID f = UnsafeNativeMethods.AuthzInitializeContextFromSid( 0, // default flags _psUserSid.DangerousGetHandle(), pResManager, IntPtr.Zero, luid, IntPtr.Zero, out pClientContext ); if (f) { int bufferSize = 0; GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx"); // Extract the group SIDs from the user's context. Determine the size of the buffer we need. f = UnsafeNativeMethods.AuthzGetInformationFromContext( pClientContext, 2, // AuthzContextInfoGroupsSids 0, out bufferSize, IntPtr.Zero ); if (!f && (bufferSize > 0) && (Marshal.GetLastWin32Error() == 122) /*ERROR_INSUFFICIENT_BUFFER*/) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Getting info from ctx (size={0})", bufferSize); Debug.Assert(bufferSize > 0); // Set up the needed buffer pBuffer = Marshal.AllocHGlobal(bufferSize); // Extract the group SIDs from the user's context, into our buffer.0 f = UnsafeNativeMethods.AuthzGetInformationFromContext( pClientContext, 2, // AuthzContextInfoGroupsSids bufferSize, out bufferSize, pBuffer ); if (f) { // Marshall the native buffer into managed SID_AND_ATTR structures. // The native buffer holds a TOKEN_GROUPS structure: // // struct TOKEN_GROUPS { // DWORD GroupCount; // SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY]; // }; // // Extract TOKEN_GROUPS.GroupCount UnsafeNativeMethods.TOKEN_GROUPS tokenGroups = (UnsafeNativeMethods.TOKEN_GROUPS)Marshal.PtrToStructure(pBuffer, typeof(UnsafeNativeMethods.TOKEN_GROUPS)); int groupCount = tokenGroups.groupCount; GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "Found {0} groups", groupCount); // Extract TOKEN_GROUPS.Groups, by iterating over the array and marshalling // each native SID_AND_ATTRIBUTES into a managed SID_AND_ATTR. UnsafeNativeMethods.SID_AND_ATTR[] groups = new UnsafeNativeMethods.SID_AND_ATTR[groupCount]; IntPtr currentItem = new IntPtr(pBuffer.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.TOKEN_GROUPS)) - IntPtr.Size); for (int i = 0; i < groupCount; i++) { groups[i] = (UnsafeNativeMethods.SID_AND_ATTR)Marshal.PtrToStructure(currentItem, typeof(UnsafeNativeMethods.SID_AND_ATTR)); currentItem = new IntPtr(currentItem.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.SID_AND_ATTR))); } _groupSidList = new SidList(groups); } else { lastError = Marshal.GetLastWin32Error(); } } else { lastError = Marshal.GetLastWin32Error(); Debug.Fail("With a zero-length buffer, this should have never succeeded"); } } else { lastError = Marshal.GetLastWin32Error(); } } else { lastError = Marshal.GetLastWin32Error(); } if (!f) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "Failed to retrieve group list, {0}", lastError); throw new PrincipalOperationException( SR.Format( SR.AuthZFailedToRetrieveGroupList, lastError)); } // Save off the buffer since it still holds the native SIDs referenced by SidList _psBuffer = new SafeMemoryPtr(pBuffer); pBuffer = IntPtr.Zero; } catch (Exception e) { GlobalDebug.WriteLineIf(GlobalDebug.Error, "AuthZSet", "Caught exception {0} with message {1}", e.GetType(), e.Message); if (_psBuffer != null && !_psBuffer.IsInvalid) { _psBuffer.Close(); } if (_psUserSid != null && !_psUserSid.IsInvalid) { _psUserSid.Close(); } if (_psMachineSid != null && !_psMachineSid.IsInvalid) { _psMachineSid.Close(); } // We're on a platform that doesn't have the AuthZ library if (e is DllNotFoundException) { throw new NotSupportedException(SR.AuthZNotSupported, e); } if (e is EntryPointNotFoundException) { throw new NotSupportedException(SR.AuthZNotSupported, e); } throw; } finally { if (pClientContext != IntPtr.Zero) { UnsafeNativeMethods.AuthzFreeContext(pClientContext); } if (pResManager != IntPtr.Zero) { UnsafeNativeMethods.AuthzFreeResourceManager(pResManager); } if (pBuffer != IntPtr.Zero) { Marshal.FreeHGlobal(pBuffer); } } }
internal AuthZSet(byte[] userSid, NetCred credentials, ContextOptions contextOptions, string flatUserAuthority, StoreCtx userStoreCtx, object userCtxBase) { this.currentGroup = -1; this.contexts = new Hashtable(); this.localMachineIsDC = null; this.userType = userStoreCtx.OwningContext.ContextType; this.userCtxBase = userCtxBase; this.userStoreCtx = userStoreCtx; this.credentials = credentials; this.contextOptions = contextOptions; this.flatUserAuthority = flatUserAuthority; this.contexts[flatUserAuthority] = userStoreCtx.OwningContext; IntPtr zero = IntPtr.Zero; IntPtr intPtr = IntPtr.Zero; IntPtr zero1 = IntPtr.Zero; try { try { UnsafeNativeMethods.LUID lUID = new UnsafeNativeMethods.LUID(); lUID.low = 0; lUID.high = 0; this.psMachineSid = new AuthZSet.SafeMemoryPtr(Utils.GetMachineDomainSid()); this.psUserSid = new AuthZSet.SafeMemoryPtr(Utils.ConvertByteArrayToIntPtr(userSid)); int lastWin32Error = 0; bool flag = UnsafeNativeMethods.AuthzInitializeResourceManager(UnsafeNativeMethods.AUTHZ_RM_FLAG.AUTHZ_RM_FLAG_NO_AUDIT, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, null, out intPtr); if (!flag) { lastWin32Error = Marshal.GetLastWin32Error(); } else { flag = UnsafeNativeMethods.AuthzInitializeContextFromSid(0, this.psUserSid.DangerousGetHandle(), intPtr, IntPtr.Zero, lUID, IntPtr.Zero, out zero); if (!flag) { lastWin32Error = Marshal.GetLastWin32Error(); } else { int num = 0; flag = UnsafeNativeMethods.AuthzGetInformationFromContext(zero, 2, 0, out num, IntPtr.Zero); if (flag || num <= 0 || Marshal.GetLastWin32Error() != 122) { lastWin32Error = Marshal.GetLastWin32Error(); } else { zero1 = Marshal.AllocHGlobal(num); flag = UnsafeNativeMethods.AuthzGetInformationFromContext(zero, 2, num, out num, zero1); if (!flag) { lastWin32Error = Marshal.GetLastWin32Error(); } else { UnsafeNativeMethods.TOKEN_GROUPS structure = (UnsafeNativeMethods.TOKEN_GROUPS)Marshal.PtrToStructure(zero1, typeof(UnsafeNativeMethods.TOKEN_GROUPS)); int num1 = structure.groupCount; UnsafeNativeMethods.SID_AND_ATTR[] sIDANDATTRArray = new UnsafeNativeMethods.SID_AND_ATTR[num1]; IntPtr intPtr1 = new IntPtr(zero1.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.TOKEN_GROUPS)) - (long)Marshal.SizeOf(typeof(IntPtr))); for (int i = 0; i < num1; i++) { sIDANDATTRArray[i] = (UnsafeNativeMethods.SID_AND_ATTR)Marshal.PtrToStructure(intPtr1, typeof(UnsafeNativeMethods.SID_AND_ATTR)); intPtr1 = new IntPtr(intPtr1.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.SID_AND_ATTR))); } this.groupSidList = new SidList(sIDANDATTRArray); } } } } if (flag) { this.psBuffer = new AuthZSet.SafeMemoryPtr(zero1); zero1 = IntPtr.Zero; } else { object[] objArray = new object[1]; objArray[0] = lastWin32Error; throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.AuthZFailedToRetrieveGroupList, objArray)); } } catch (Exception exception1) { Exception exception = exception1; if (this.psBuffer != null && !this.psBuffer.IsInvalid) { this.psBuffer.Close(); } if (this.psUserSid != null && !this.psUserSid.IsInvalid) { this.psUserSid.Close(); } if (this.psMachineSid != null && !this.psMachineSid.IsInvalid) { this.psMachineSid.Close(); } if (exception as DllNotFoundException == null) { if (exception as EntryPointNotFoundException == null) { throw; } else { throw new NotSupportedException(StringResources.AuthZNotSupported, exception); } } else { throw new NotSupportedException(StringResources.AuthZNotSupported, exception); } } } finally { if (zero != IntPtr.Zero) { UnsafeNativeMethods.AuthzFreeContext(zero); } if (intPtr != IntPtr.Zero) { UnsafeNativeMethods.AuthzFreeResourceManager(intPtr); } if (zero1 != IntPtr.Zero) { Marshal.FreeHGlobal(zero1); } } }