예제 #1
0
        internal static NtResult <CentralAccessRule> FromRegistry(NtKey key, bool throw_on_error)
        {
            string             name        = string.Empty;
            string             description = string.Empty;
            SecurityDescriptor sd          = null;
            SecurityDescriptor staged_sd   = null;
            string             applies_to  = string.Empty;
            string             change_id   = string.Empty;
            uint flags = 0;

            foreach (var value in key.QueryValues())
            {
                switch (value.Name.ToLower())
                {
                case "appliesto":
                    if (value.Data.Length > 0)
                    {
                        var result = NtSecurity.ConditionalAceToString(value.Data, throw_on_error);
                        if (!result.IsSuccess)
                        {
                            return(result.Cast <CentralAccessRule>());
                        }
                        applies_to = result.Result;
                    }
                    break;

                case "sd":
                {
                    if (value.Data.Length > 0)
                    {
                        var sd_result = SecurityDescriptor.Parse(value.Data, throw_on_error);
                        if (!sd_result.IsSuccess)
                        {
                            return(sd_result.Cast <CentralAccessRule>());
                        }
                        sd = sd_result.Result;
                    }
                }
                break;

                case "stagedsd":
                {
                    if (value.Data.Length > 0)
                    {
                        var sd_result = SecurityDescriptor.Parse(value.Data, throw_on_error);
                        if (!sd_result.IsSuccess)
                        {
                            return(sd_result.Cast <CentralAccessRule>());
                        }
                        staged_sd = sd_result.Result;
                    }
                }
                break;

                case "changeid":
                    change_id = value.ToString().TrimEnd('\0');
                    break;

                case "description":
                    description = value.ToString().TrimEnd('\0');
                    break;

                case "flags":
                    if (value.Type == RegistryValueType.Dword)
                    {
                        flags = (uint)value.ToObject();
                    }
                    break;

                case "name":
                    name = value.ToString().TrimEnd('\0');
                    break;
                }
            }
            return(new CentralAccessRule(name, description, sd, staged_sd, applies_to, change_id, flags).CreateResult());
        }
예제 #2
0
        /// <summary>
        /// Parse the policy from the Local Security Authority.
        /// </summary>
        /// <param name="throw_on_error">True to throw on error.</param>
        /// <returns>The list of Central Access Policies.</returns>
        public static NtResult <CentralAccessPolicy[]> ParseFromLsa(bool throw_on_error)
        {
            NtStatus status = SecurityNativeMethods.LsaGetAppliedCAPIDs(null, out SafeLsaMemoryBuffer capids, out int capid_count);

            if (!status.IsSuccess())
            {
                return(status.CreateResultFromError <CentralAccessPolicy[]>(throw_on_error));
            }
            List <CentralAccessPolicy> ret = new List <CentralAccessPolicy>();

            using (capids) {
                status = SecurityNativeMethods.LsaQueryCAPs(capids.DangerousGetHandle(), capid_count, out SafeLsaMemoryBuffer caps, out uint cap_count);
                if (!status.IsSuccess())
                {
                    return(status.CreateResultFromError <CentralAccessPolicy[]>(throw_on_error));
                }
                caps.Initialize <CENTRAL_ACCESS_POLICY>(cap_count);
                CENTRAL_ACCESS_POLICY[] policies = new CENTRAL_ACCESS_POLICY[cap_count];
                caps.ReadArray(0, policies, 0, policies.Length);
                foreach (var policy in policies)
                {
                    SafeHGlobalBuffer buffer       = new SafeHGlobalBuffer(policy.CAPEs, policy.CAPECount * IntPtr.Size, false);
                    IntPtr[]          rule_entries = new IntPtr[policy.CAPECount];
                    buffer.ReadArray(0, rule_entries, 0, policy.CAPECount);
                    List <CentralAccessRule> rules = new List <CentralAccessRule>();
                    foreach (var ptr in rule_entries)
                    {
                        var entry                     = new SafeStructureInOutBuffer <CENTRAL_ACCESS_POLICY_ENTRY>(ptr, Marshal.SizeOf(typeof(CENTRAL_ACCESS_POLICY_ENTRY)), false);
                        var r                         = entry.Result;
                        SecurityDescriptor sd         = null;
                        SecurityDescriptor staged_sd  = null;
                        string             applies_to = string.Empty;
                        if (r.LengthSD > 0)
                        {
                            var result = SecurityDescriptor.Parse(r.SD, throw_on_error);
                            if (!result.IsSuccess)
                            {
                                return(result.Cast <CentralAccessPolicy[]>());
                            }
                            sd = result.Result;
                        }
                        if (r.LengthStagedSD > 0)
                        {
                            var result = SecurityDescriptor.Parse(r.StagedSD, throw_on_error);
                            if (!result.IsSuccess)
                            {
                                return(result.Cast <CentralAccessPolicy[]>());
                            }
                            staged_sd = result.Result;
                        }
                        if (r.LengthAppliesTo > 0)
                        {
                            byte[] condition = new byte[r.LengthAppliesTo];
                            Marshal.Copy(r.AppliesTo, condition, 0, r.LengthAppliesTo);
                            var result = NtSecurity.ConditionalAceToString(condition, throw_on_error);
                            if (!result.IsSuccess)
                            {
                                return(result.Cast <CentralAccessPolicy[]>());
                            }
                            applies_to = result.Result;
                        }

                        rules.Add(new CentralAccessRule(r.Name.ToString(), r.Description.ToString(),
                                                        sd, staged_sd, applies_to, r.ChangeId.ToString(), r.Flags));
                    }
                    var capid = Sid.Parse(policy.CAPID, throw_on_error);
                    if (!capid.IsSuccess)
                    {
                        return(capid.Cast <CentralAccessPolicy[]>());
                    }
                    ret.Add(new CentralAccessPolicy(capid.Result, policy.Flags, policy.Name.ToString(),
                                                    policy.Description.ToString(), policy.ChangeId.ToString(), rules));
                }
            }
            return(ret.ToArray().CreateResult());
        }