示例#1
0
        /// <summary>
        /// Creates a Windows SID Claim and adds to collection of claims.
        /// </summary>
        private void AddPrimarySidClaim(List<Claim> instanceClaims)
        {
            // special case the anonymous identity.
            if (_safeTokenHandle.IsInvalid)
                return;

            SafeLocalAllocHandle safeAllocHandle = SafeLocalAllocHandle.InvalidHandle;
            try
            {
                safeAllocHandle = GetTokenInformation(_safeTokenHandle, TokenInformationClass.TokenUser);
                Interop.SID_AND_ATTRIBUTES user = (Interop.SID_AND_ATTRIBUTES)Marshal.PtrToStructure<Interop.SID_AND_ATTRIBUTES>(safeAllocHandle.DangerousGetHandle());
                uint mask = Interop.SecurityGroups.SE_GROUP_USE_FOR_DENY_ONLY;

                SecurityIdentifier sid = new SecurityIdentifier(user.Sid, true);
                Claim claim;
                if (user.Attributes == 0)
                {
                    claim = new Claim(ClaimTypes.PrimarySid, sid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                    claim.Properties.Add(ClaimTypes.WindowsSubAuthority, sid.IdentifierAuthority.ToString());
                    instanceClaims.Add(claim);
                }
                else if ((user.Attributes & mask) == Interop.SecurityGroups.SE_GROUP_USE_FOR_DENY_ONLY)
                {
                    claim = new Claim(ClaimTypes.DenyOnlyPrimarySid, sid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                    claim.Properties.Add(ClaimTypes.WindowsSubAuthority, sid.IdentifierAuthority.ToString());
                    instanceClaims.Add(claim);
                }
            }
            finally
            {
                safeAllocHandle.Dispose();
            }
        }
示例#2
0
        /// <summary>
        /// Creates a collection of SID claims that represent the users groups.
        /// </summary>
        private void AddGroupSidClaims(List <Claim> instanceClaims)
        {
            // special case the anonymous identity.
            if (_safeTokenHandle.IsInvalid)
            {
                return;
            }

            SafeLocalAllocHandle safeAllocHandle             = SafeLocalAllocHandle.InvalidHandle;
            SafeLocalAllocHandle safeAllocHandlePrimaryGroup = SafeLocalAllocHandle.InvalidHandle;

            try
            {
                // Retrieve the primary group sid
                safeAllocHandlePrimaryGroup = GetTokenInformation(_safeTokenHandle, TokenInformationClass.TokenPrimaryGroup);
                Interop.TOKEN_PRIMARY_GROUP primaryGroup    = (Interop.TOKEN_PRIMARY_GROUP)Marshal.PtrToStructure <Interop.TOKEN_PRIMARY_GROUP>(safeAllocHandlePrimaryGroup.DangerousGetHandle());
                SecurityIdentifier          primaryGroupSid = new SecurityIdentifier(primaryGroup.PrimaryGroup, true);

                // only add one primary group sid
                bool foundPrimaryGroupSid = false;

                // Retrieve all group sids, primary group sid is one of them
                safeAllocHandle = GetTokenInformation(_safeTokenHandle, TokenInformationClass.TokenGroups);
                int    count             = Marshal.ReadInt32(safeAllocHandle.DangerousGetHandle());
                IntPtr pSidAndAttributes = new IntPtr((long)safeAllocHandle.DangerousGetHandle() + (long)Marshal.OffsetOf <Interop.TOKEN_GROUPS>("Groups"));
                Claim  claim;
                for (int i = 0; i < count; ++i)
                {
                    Interop.SID_AND_ATTRIBUTES group = (Interop.SID_AND_ATTRIBUTES)Marshal.PtrToStructure <Interop.SID_AND_ATTRIBUTES>(pSidAndAttributes);
                    uint mask = Interop.SecurityGroups.SE_GROUP_ENABLED | Interop.SecurityGroups.SE_GROUP_LOGON_ID | Interop.SecurityGroups.SE_GROUP_USE_FOR_DENY_ONLY;
                    SecurityIdentifier groupSid = new SecurityIdentifier(group.Sid, true);

                    if ((group.Attributes & mask) == Interop.SecurityGroups.SE_GROUP_ENABLED)
                    {
                        if (!foundPrimaryGroupSid && StringComparer.Ordinal.Equals(groupSid.Value, primaryGroupSid.Value))
                        {
                            claim = new Claim(ClaimTypes.PrimaryGroupSid, groupSid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                            claim.Properties.Add(ClaimTypes.WindowsSubAuthority, groupSid.IdentifierAuthority.ToString());
                            instanceClaims.Add(claim);
                            foundPrimaryGroupSid = true;
                        }
                        //Primary group sid generates both regular groupsid claim and primary groupsid claim
                        claim = new Claim(ClaimTypes.GroupSid, groupSid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                        claim.Properties.Add(ClaimTypes.WindowsSubAuthority, groupSid.IdentifierAuthority.ToString());
                        instanceClaims.Add(claim);
                    }
                    else if ((group.Attributes & mask) == Interop.SecurityGroups.SE_GROUP_USE_FOR_DENY_ONLY)
                    {
                        if (!foundPrimaryGroupSid && StringComparer.Ordinal.Equals(groupSid.Value, primaryGroupSid.Value))
                        {
                            claim = new Claim(ClaimTypes.DenyOnlyPrimaryGroupSid, groupSid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                            claim.Properties.Add(ClaimTypes.WindowsSubAuthority, groupSid.IdentifierAuthority.ToString());
                            instanceClaims.Add(claim);
                            foundPrimaryGroupSid = true;
                        }
                        //Primary group sid generates both regular groupsid claim and primary groupsid claim
                        claim = new Claim(ClaimTypes.DenyOnlySid, groupSid.Value, ClaimValueTypes.String, _issuerName, _issuerName, this);
                        claim.Properties.Add(ClaimTypes.WindowsSubAuthority, groupSid.IdentifierAuthority.ToString());
                        instanceClaims.Add(claim);
                    }
                    pSidAndAttributes = new IntPtr((long)pSidAndAttributes + Marshal.SizeOf <Interop.SID_AND_ATTRIBUTES>());
                }
            }
            finally
            {
                safeAllocHandle.Dispose();
                safeAllocHandlePrimaryGroup.Dispose();
            }
        }
示例#3
0
文件: AuthZSet.cs 项目: z77ma/runtime
        internal unsafe 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;
            _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;

            //
            // Get the SIDs of the groups to which the user belongs
            //

            IntPtr pClientContext = IntPtr.Zero;
            IntPtr pResManager    = IntPtr.Zero;
            IntPtr pBuffer        = IntPtr.Zero;

            try
            {
                Interop.LUID luid = default;

                _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 = Interop.Authz.AuthzInitializeResourceManager(
                    Interop.Authz.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 = Interop.Authz.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 = Interop.Authz.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 = Interop.Authz.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

                                Interop.TOKEN_GROUPS tokenGroups = (Interop.TOKEN_GROUPS)Marshal.PtrToStructure(pBuffer, typeof(Interop.TOKEN_GROUPS));

                                uint 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.
                                Interop.SID_AND_ATTRIBUTES[] groups = new Interop.SID_AND_ATTRIBUTES[groupCount];

                                IntPtr currentItem = new IntPtr(pBuffer.ToInt64() + Marshal.SizeOf(typeof(Interop.TOKEN_GROUPS)) - sizeof(Interop.SID_AND_ATTRIBUTES));

                                for (int i = 0; i < groupCount; i++)
                                {
                                    groups[i] = (Interop.SID_AND_ATTRIBUTES)Marshal.PtrToStructure(currentItem, typeof(Interop.SID_AND_ATTRIBUTES));

                                    currentItem = new IntPtr(currentItem.ToInt64() + Marshal.SizeOf(typeof(Interop.SID_AND_ATTRIBUTES)));
                                }

                                _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)
                {
                    Interop.Authz.AuthzFreeContext(pClientContext);
                }

                if (pResManager != IntPtr.Zero)
                {
                    Interop.Authz.AuthzFreeResourceManager(pResManager);
                }

                if (pBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pBuffer);
                }
            }
        }