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()); }
/// <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()); }