コード例 #1
0
        /// <summary>
        /// Computes effective access rights upon acquiring the necessary security information such as Share's security,
        /// Central Policy and Resource's security as maybe applicable.
        /// </summary>
        public void Evaluate()
        {
            using (TokenPrivilege seSecurityPrivilege = new TokenPrivilege(TokenPrivilege.Security))
            {
                try
                {
                    //
                    // SeSecurityPrivilege is required for querying the Central Policy ID (Scope information) from the
                    // file's SD
                    //
                    seSecurityPrivilege.Enable();

                    var securityObjects = new Dictionary <string, FileSecurityObject>();

                    //
                    // First include the Share's SD if available. If the share denies a permission, anything else that
                    // denies a permission is of lesser consequence.
                    //
                    if (shareSD != null)
                    {
                        securityObjects.Add("Share", new FileSecurityObject(shareSD));
                    }

                    SecurityIdentifier capId = null;
                    {
                        RawSecurityDescriptor scopeSD = GetFileSecInfoSD(handle,
                                                                         NativeMethods.SecurityInformationClass.Scope);
                        if (scopeSD != null)
                        {
                            if (scopeSD.SystemAcl != null)
                            {
                                foreach (GenericAce ace in scopeSD.SystemAcl)
                                {
                                    //
                                    // Scoped Policy ID ACE not yet part of System.Security.AccessControl.AceType
                                    //
                                    // Since SYSTEM_SCOPED_POLICY_ID_ACE essentially has a SID which is the identifier
                                    // for a Central Policy, extract it explicitly.
                                    //
                                    byte[] rawAce = new byte[ace.BinaryLength];
                                    ace.GetBinaryForm(rawAce, 0);

                                    if ((ace.AceFlags & AceFlags.InheritOnly) == 0)
                                    {
                                        long sidOffset = (long)Marshal.OffsetOf(
                                            typeof(NativeMethods.SYSTEM_SCOPED_POLICY_ID_ACE),
                                            "SidStart");

                                        if (sidOffset < ace.BinaryLength)
                                        {
                                            capId = new SecurityIdentifier(rawAce, (int)sidOffset);

                                            //
                                            // The first Central Policy is the only one honored when there are multiple
                                            // in a Security Descriptor. Ignore everything else.
                                            //
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    //
                    // Obtain file SD
                    //
                    RawSecurityDescriptor fileSD = GetFileSecInfoSD(
                        handle,
                        NativeMethods.SecurityInformationClass.Owner
                        | NativeMethods.SecurityInformationClass.Group
                        | NativeMethods.SecurityInformationClass.Dacl
                        | NativeMethods.SecurityInformationClass.Label
                        | NativeMethods.SecurityInformationClass.Attribute);
                    if (capId != null)
                    {
                        var availableCaps = new AvailableCentralPolicies(targetMachine);

                        Dictionary <string, CentralAccessRule> CARs = availableCaps.FetchCentralAccessRules(capId);

                        if (CARs == null || CARs.Count == 0)
                        {
                            //
                            // If the Central Policy or any of its Central Access Rules could not be retrieved, fall
                            // back to just the granularity of Central Policy. For this, use the file's SD with the
                            // CAP ID.
                            //
                            securityObjects.Add("Central Policy",
                                                new FileSecurityObject(
                                                    GetFileSecInfoSD(handle,
                                                                     NativeMethods.SecurityInformationClass.Owner
                                                                     | NativeMethods.SecurityInformationClass.Group
                                                                     | NativeMethods.SecurityInformationClass.Label
                                                                     | NativeMethods.SecurityInformationClass.Attribute
                                                                     | NativeMethods.SecurityInformationClass.Scope)));
                        }
                        else
                        {
                            //
                            // The merged security descriptor for each Central Access Rule is generated as follows:
                            //   Owner + Group + SACL (all from resource's SD) + DACL from Central Access Rule
                            //
                            // If the AppliesTo predicate is present, then we do the following:
                            //   Owned + Group + SACL (all from resource's SD)
                            //   + A fabricated DACL with an allowed callback ACE containingn the selected user
                            //     principal and the AppliesTo predicate appended.
                            //
                            foreach (var rule in CARs)
                            {
                                var sd = new RawSecurityDescriptor(fileSD.ControlFlags,
                                                                   fileSD.Owner,
                                                                   fileSD.Group,
                                                                   fileSD.SystemAcl,
                                                                   rule.Value.EffectivePolicy.DiscretionaryAcl);

                                if (!string.IsNullOrEmpty(rule.Value.AppliesToCondition))
                                {
                                    string appliesToSDDL = "D:(XA;;FR;;;" + userSid.ToString() + ";" +
                                                           rule.Value.AppliesToCondition + ")";

                                    var appliesToSD = new RawSecurityDescriptor(
                                        fileSD.ControlFlags,
                                        fileSD.Owner,
                                        fileSD.Group,
                                        fileSD.SystemAcl,
                                        (new RawSecurityDescriptor(appliesToSDDL)).DiscretionaryAcl);

                                    securityObjects.Add(rule.Key, new FileSecurityObject(sd, appliesToSD));
                                }
                                else
                                {
                                    securityObjects.Add(rule.Key, new FileSecurityObject(sd));
                                }
                            }
                        }
                    }

                    securityObjects.Add("File permissions", new FileSecurityObject(fileSD));

                    results = ComputeEffectiveAccessResult(targetMachine, securityObjects);
                }
                finally
                {
                    seSecurityPrivilege.Revert();
                }
            }
        }
コード例 #2
0
        /// <summary>
        /// Computes effective access rights upon acquiring the necessary security information such as Share's security,
        /// Central Policy and Resource's security as maybe applicable.
        /// </summary>
        public void Evaluate()
        {
            using (TokenPrivilege seSecurityPrivilege = new TokenPrivilege(TokenPrivilege.Security))
            {
                try
                {
                    //
                    // SeSecurityPrivilege is required for querying the Central Policy ID (Scope information) from the
                    // file's SD
                    //
                    seSecurityPrivilege.Enable();

                    var securityObjects = new Dictionary<string, FileSecurityObject>();

                    //
                    // First include the Share's SD if available. If the share denies a permission, anything else that
                    // denies a permission is of lesser consequence.
                    //
                    if (shareSD != null)
                    {
                        securityObjects.Add("Share", new FileSecurityObject(shareSD));
                    }

                    SecurityIdentifier capId = null;
                    {
                        RawSecurityDescriptor scopeSD = GetFileSecInfoSD(handle,
                                                                         NativeMethods.SecurityInformationClass.Scope);
                        if (scopeSD != null)
                        {
                            if (scopeSD.SystemAcl != null)
                            {
                                foreach (GenericAce ace in scopeSD.SystemAcl)
                                {
                                    //
                                    // Scoped Policy ID ACE not yet part of System.Security.AccessControl.AceType
                                    //
                                    // Since SYSTEM_SCOPED_POLICY_ID_ACE essentially has a SID which is the identifier
                                    // for a Central Policy, extract it explicitly.
                                    //
                                    byte[] rawAce = new byte[ace.BinaryLength];
                                    ace.GetBinaryForm(rawAce, 0);

                                    if ((ace.AceFlags & AceFlags.InheritOnly) == 0)
                                    {
                                        long sidOffset = (long)Marshal.OffsetOf(
                                                                    typeof(NativeMethods.SYSTEM_SCOPED_POLICY_ID_ACE),
                                                                    "SidStart");

                                        if (sidOffset < ace.BinaryLength)
                                        {
                                            capId = new SecurityIdentifier(rawAce, (int)sidOffset);

                                            //
                                            // The first Central Policy is the only one honored when there are multiple
                                            // in a Security Descriptor. Ignore everything else.
                                            //
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    //
                    // Obtain file SD
                    //
                    RawSecurityDescriptor fileSD = GetFileSecInfoSD(
                                                        handle,
                                                          NativeMethods.SecurityInformationClass.Owner
                                                        | NativeMethods.SecurityInformationClass.Group
                                                        | NativeMethods.SecurityInformationClass.Dacl
                                                        | NativeMethods.SecurityInformationClass.Label
                                                        | NativeMethods.SecurityInformationClass.Attribute);
                    if (capId != null)
                    {
                        var availableCaps = new AvailableCentralPolicies(targetMachine);

                        Dictionary<string, CentralAccessRule> CARs = availableCaps.FetchCentralAccessRules(capId);

                        if (CARs == null || CARs.Count == 0)
                        {
                            //
                            // If the Central Policy or any of its Central Access Rules could not be retrieved, fall
                            // back to just the granularity of Central Policy. For this, use the file's SD with the
                            // CAP ID.
                            //
                            securityObjects.Add("Central Policy",
                                                new FileSecurityObject(
                                                        GetFileSecInfoSD(handle,
                                                          NativeMethods.SecurityInformationClass.Owner
                                                        | NativeMethods.SecurityInformationClass.Group
                                                        | NativeMethods.SecurityInformationClass.Label
                                                        | NativeMethods.SecurityInformationClass.Attribute
                                                        | NativeMethods.SecurityInformationClass.Scope)));
                        }
                        else
                        {
                            //
                            // The merged security descriptor for each Central Access Rule is generated as follows:
                            //   Owner + Group + SACL (all from resource's SD) + DACL from Central Access Rule
                            //
                            // If the AppliesTo predicate is present, then we do the following:
                            //   Owned + Group + SACL (all from resource's SD)
                            //   + A fabricated DACL with an allowed callback ACE containingn the selected user
                            //     principal and the AppliesTo predicate appended.
                            //
                            foreach (var rule in CARs)
                            {
                                var sd = new RawSecurityDescriptor(fileSD.ControlFlags,
                                                                   fileSD.Owner,
                                                                   fileSD.Group,
                                                                   fileSD.SystemAcl,
                                                                   rule.Value.EffectivePolicy.DiscretionaryAcl);

                                if (!string.IsNullOrEmpty(rule.Value.AppliesToCondition))
                                {
                                    string appliesToSDDL = "D:(XA;;FR;;;" + userSid.ToString() + ";" +
                                                           rule.Value.AppliesToCondition + ")";

                                    var appliesToSD = new RawSecurityDescriptor(
                                                            fileSD.ControlFlags,
                                                            fileSD.Owner,
                                                            fileSD.Group,
                                                            fileSD.SystemAcl,
                                                            (new RawSecurityDescriptor(appliesToSDDL)).DiscretionaryAcl);

                                    securityObjects.Add(rule.Key, new FileSecurityObject(sd, appliesToSD));
                                }
                                else
                                {
                                    securityObjects.Add(rule.Key, new FileSecurityObject(sd));
                                }
                            }
                        }
                    }

                    securityObjects.Add("File permissions", new FileSecurityObject(fileSD));

                    results = ComputeEffectiveAccessResult(targetMachine, securityObjects);
                }
                finally
                {
                    seSecurityPrivilege.Revert();
                }
            }
        }