using System;
using System.Collections.Generic;
using System.Security.AccessControl;
using System.Security.Principal;
using Vanara.Extensions;
using Vanara.PInvoke;
using static Vanara.PInvoke.AdvApi32;
namespace Vanara.Security
{
public static partial class AccountUtils
{
/// Represents a central access policy that contains a set of central access policy entries.
public class CentralAccessPolicy
{
internal CentralAccessPolicy(in CENTRAL_ACCESS_POLICY cap)
{
Id = new SecurityIdentifier(cap.CAPID.DangerousGetHandle());
Name = cap.Name;
ChangeId = cap.ChangeId;
Entries = Array.ConvertAll(cap.CAPEs.ToArray((int)cap.CAPECount), e => new CentralAccessPolicyEntry(e));
}
/// An identifier that can be used to version the central access policy.
public string ChangeId { get; }
/// The description of the central access policy.
/// Pointer to a buffer of CENTRAL_ACCESS_POLICY_ENTRY pointers.
public CentralAccessPolicyEntry[] Entries { get; }
/// The identifier of the central access policy.
public SecurityIdentifier Id { get; }
/// The name of the central access policy.
public string Name { get; }
///
/// Returns a seqence of central access policies (CAPs) identifiers (CAPIDs) of all the CAPs applied on a specific computer.
///
///
/// The name of the specific computer. The name can have the form of "ComputerName" or "\ComputerName". If this parameter is
/// , then the function returns the CAPIDs of the local computer.
///
///
/// A sequence of instances that identify the CAPs available on the specified computer.
///
///
/// For specific details about the central access policies, you can query the attributes of the central access policy object in
/// the Active Directory on the specified computer's domain controller. Look for the object whose
/// msAuthz-CentralAccessPolicyID attribute matches one of the returned CAPIDs.
///
public static IEnumerable GetAppliedPolicies(string systemName = null)
{
LsaGetAppliedCAPIDs(systemName, out var h, out var c).ThrowIfFailed();
using (h)
{
LsaQueryCAPs(h.DangerousGetHandle(), c, out var ch, out var cc).ThrowIfFailed();
using (ch)
{
return Array.ConvertAll(ch.ToArray((int)cc), e => new CentralAccessPolicy(e));
}
}
}
/// Returns the Central Access Policies (CAPs) for the specified IDs.
/// An array of pointers to CAPIDs that identify the CAPs being queried.
///
/// A sequence of instances that identify the CAPs available on the specified computer.
///
public static IEnumerable GetPoliciesForIds(params PSID[] capids)
{
LsaQueryCAPs(capids, (uint)capids.Length, out var ch, out var cc).ThrowIfFailed();
using (ch)
{
return Array.ConvertAll(ch.ToArray((int)cc), e => new CentralAccessPolicy(e));
}
}
}
/// Represents a central access policy entry containing a list of security descriptors and staged security descriptors.
public class CentralAccessPolicyEntry
{
internal CentralAccessPolicyEntry(in CENTRAL_ACCESS_POLICY_ENTRY cape)
{
Name = cape.Name;
Description = cape.Description;
ChangeId = cape.ChangeId;
AppliesTo = cape.AppliesTo.ToArray((int)cape.LengthAppliesTo);
SecurityDescriptor = cape.SD.ToManaged();
StagedSecurityDescriptor = cape.StagedSD.ToManaged();
}
/// A resource condition in binary form.
public byte[] AppliesTo { get; }
/// An identifier that can be used to version the central access policy entry.
public string ChangeId { get; }
/// The description of the central access policy entry.
public string Description { get; }
/// The name of the central access policy entry.
public string Name { get; }
/// A buffer of security descriptors associated with the entry.
public RawSecurityDescriptor SecurityDescriptor { get; }
/// A buffer of staged security descriptors associated with the entry.
public RawSecurityDescriptor StagedSecurityDescriptor { get; }
}
}
}