mirror of https://github.com/dahall/Vanara.git
Collapsed SafeLocalPSID into SafePSID. Enhanced SafePSIDArray.
Finished unit testing and changes for Lsa** functions.pull/83/head
parent
198a3fafd5
commit
0c73576e40
|
@ -48,10 +48,7 @@ namespace Vanara.PInvoke
|
|||
/// <summary>Should be <c>NULL</c>.</summary>
|
||||
public IntPtr SecurityQualityOfService;
|
||||
|
||||
/// <summary>
|
||||
/// Returns a completely empty reference. This value should be used when calling <see cref="LsaOpenPolicy(string, ref
|
||||
/// LSA_OBJECT_ATTRIBUTES, LsaPolicyRights, out SafeLSA_HANDLE)"/>.
|
||||
/// </summary>
|
||||
/// <summary>Returns a completely empty reference. This value should be used when calling <see cref="LsaOpenPolicy(string, ref LSA_OBJECT_ATTRIBUTES, LsaPolicyRights, out SafeLSA_HANDLE)"/>.</summary>
|
||||
/// <value>An <see cref="LSA_OBJECT_ATTRIBUTES"/> instance with all members set to <c>NULL</c> or zero.</value>
|
||||
public static LSA_OBJECT_ATTRIBUTES Empty { get; } = new LSA_OBJECT_ATTRIBUTES();
|
||||
}
|
||||
|
@ -160,7 +157,7 @@ namespace Vanara.PInvoke
|
|||
public SID_NAME_USE Use;
|
||||
|
||||
/// <summary>The complete SID of the account.</summary>
|
||||
public IntPtr Sid;
|
||||
public PSID Sid;
|
||||
|
||||
/// <summary>
|
||||
/// The index of an entry in a related LSA_REFERENCED_DOMAIN_LIST data structure which describes the domain that owns the
|
||||
|
@ -196,7 +193,7 @@ namespace Vanara.PInvoke
|
|||
var s = ManagedObj as string;
|
||||
if (s == null) return IntPtr.Zero;
|
||||
var str = new LSA_STRING(s);
|
||||
return str.StructureToPtr(Marshal.AllocCoTaskMem, out int _);
|
||||
return str.StructureToPtr(Marshal.AllocCoTaskMem, out var _);
|
||||
}
|
||||
|
||||
public object MarshalNativeToManaged(IntPtr pNativeData)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace Vanara.PInvoke
|
||||
|
@ -82,12 +83,12 @@ namespace Vanara.PInvoke
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The LsaGetAppliedCAPIDs function returns an array of central access policies (CAPs) identifiers (CAPIDs) of all the CAPs applied
|
||||
/// on a specific computer.
|
||||
/// The <c>LsaGetAppliedCAPIDs</c> function returns an array of central access policies (CAPs) identifiers (CAPIDs) of all the CAPs
|
||||
/// applied on a specific computer.
|
||||
/// </summary>
|
||||
/// <param name="systemName">
|
||||
/// The name of the specific computer. The name can have the form of "ComputerName" or "\\ComputerName". If this parameter is NULL,
|
||||
/// then the function returns the CAPIDs of the local computer.
|
||||
/// <param name="SystemName">
|
||||
/// A pointer to an LSA_UNICODE_STRING structure that contains the name of the specific computer. The name can have the form of
|
||||
/// "ComputerName" or "\ComputerName". If this parameter is <c>NULL</c>, then the function returns the CAPIDs of the local computer.
|
||||
/// </param>
|
||||
/// <param name="CAPIDs">
|
||||
/// A pointer to a variable that receives an array of pointers to CAPIDs that identify the CAPs available on the specified computer.
|
||||
|
@ -98,18 +99,46 @@ namespace Vanara.PInvoke
|
|||
/// CAPIDs parameter contains the same number of elements as the CAPIDCount parameter.
|
||||
/// </param>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is STATUS_SUCCESS.
|
||||
/// <para>If the function succeeds, the return value is STATUS_SUCCESS.</para>
|
||||
/// <para>
|
||||
/// If the function fails, the return value is one of the LSA Policy Function Return Values. You can use the LsaNtStatusToWinError
|
||||
/// function to convert the NTSTATUS code to a Windows error code.
|
||||
/// function to convert the <c>NTSTATUS</c> code to a Windows error code.
|
||||
/// </para>
|
||||
/// </returns>
|
||||
[DllImport(Lib.AdvApi32, ExactSpelling = true, SetLastError = true, CharSet = CharSet.Unicode)]
|
||||
[PInvokeData("ntlsa.h", MSDNShortId = "hh846251")]
|
||||
/// <remarks>
|
||||
/// 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 <c>msAuthz-CentralAccessPolicyID</c>
|
||||
/// attribute matches one of the returned CAPIDs.
|
||||
/// </remarks>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntlsa/nf-ntlsa-lsagetappliedcapids
|
||||
// NTSTATUS LsaGetAppliedCAPIDs( PLSA_UNICODE_STRING SystemName, PSID **CAPIDs, PULONG CAPIDCount );
|
||||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("ntlsa.h", MSDNShortId = "DF10F5CE-BBF5-4CA8-919B-F59B7775C983")]
|
||||
public static extern NTStatus LsaGetAppliedCAPIDs(
|
||||
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string systemName,
|
||||
[In, Optional, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string systemName,
|
||||
out SafeLsaMemoryHandle CAPIDs, out uint CAPIDCount);
|
||||
|
||||
/// <summary>
|
||||
/// The <c>LsaGetAppliedCAPIDs</c> function returns an array of central access policies (CAPs) identifiers (CAPIDs) of all the CAPs
|
||||
/// applied on a specific computer.
|
||||
/// </summary>
|
||||
/// <param name="SystemName">
|
||||
/// A pointer to an LSA_UNICODE_STRING structure that contains the name of the specific computer. The name can have the form of
|
||||
/// "ComputerName" or "\ComputerName". If this parameter is <c>NULL</c>, then the function returns the CAPIDs of the local computer.
|
||||
/// </param>
|
||||
/// <returns>An array of pointers to CAPIDs that identify the CAPs available on the specified computer.</returns>
|
||||
/// <remarks>
|
||||
/// 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 <c>msAuthz-CentralAccessPolicyID</c>
|
||||
/// attribute matches one of the returned CAPIDs.
|
||||
/// </remarks>
|
||||
[PInvokeData("ntlsa.h", MSDNShortId = "DF10F5CE-BBF5-4CA8-919B-F59B7775C983")]
|
||||
public static IEnumerable<PSID> LsaGetAppliedCAPIDs([Optional] string systemName)
|
||||
{
|
||||
LsaGetAppliedCAPIDs(systemName, out var pCapIds, out var idCnt).ThrowIfFailed();
|
||||
return pCapIds.ToArray<PSID>((int)idCnt);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Retrieves the locally unique identifier (LUID) used by the Local Security Authority (LSA) to represent the specified privilege name.
|
||||
|
@ -159,7 +188,7 @@ namespace Vanara.PInvoke
|
|||
// CAPIDCount, PCENTRAL_ACCESS_POLICY *CAPs, PULONG CAPCount );
|
||||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("ntlsa.h", MSDNShortId = "55D6FD6F-0FD5-41F6-967B-F5600E19C3EF")]
|
||||
public static extern NTStatus LsaQueryCAPs([In] IntPtr[] CAPIDs, uint CAPIDCount, SafeLsaMemoryHandle CAPs, out uint CAPCount);
|
||||
public static extern NTStatus LsaQueryCAPs([In] PSID[] CAPIDs, uint CAPIDCount, out SafeLsaMemoryHandle CAPs, out uint CAPCount);
|
||||
|
||||
/// <summary>
|
||||
/// <para>Represents a central access policy that contains a set of central access policy entries.</para>
|
||||
|
@ -174,7 +203,7 @@ namespace Vanara.PInvoke
|
|||
/// <summary>
|
||||
/// <para>The identifier of the central access policy.</para>
|
||||
/// </summary>
|
||||
public IntPtr CAPID;
|
||||
public PSID CAPID;
|
||||
|
||||
/// <summary>
|
||||
/// <para>The name of the central access policy.</para>
|
||||
|
@ -251,7 +280,7 @@ namespace Vanara.PInvoke
|
|||
/// <summary>
|
||||
/// <para>A buffer of security descriptors associated with the entry.</para>
|
||||
/// </summary>
|
||||
public IntPtr SD;
|
||||
public PSECURITY_DESCRIPTOR SD;
|
||||
|
||||
/// <summary>
|
||||
/// <para>The length of the buffer pointed to by the StagedSD field.</para>
|
||||
|
@ -261,7 +290,7 @@ namespace Vanara.PInvoke
|
|||
/// <summary>
|
||||
/// <para>A buffer of staged security descriptors associated with the entry.</para>
|
||||
/// </summary>
|
||||
public IntPtr StagedSD;
|
||||
public PSECURITY_DESCRIPTOR StagedSD;
|
||||
|
||||
/// <summary>
|
||||
/// <para>This field is reserved.</para>
|
||||
|
|
|
@ -81,36 +81,52 @@ namespace Vanara.PInvoke
|
|||
[Flags]
|
||||
public enum LSA_TLN
|
||||
{
|
||||
/// <summary>The top-level name trust record is disabled during initial creation.<note type="note">This flag MUST be used only
|
||||
/// with forest trust record types of ForestTrustTopLevelName and ForestTrustTopLevelNameEx.</note></summary>
|
||||
/// <summary>
|
||||
/// The top-level name trust record is disabled during initial creation. <note type="note">This flag MUST be used only with
|
||||
/// forest trust record types of ForestTrustTopLevelName and ForestTrustTopLevelNameEx.</note>
|
||||
/// </summary>
|
||||
LSA_TLN_DISABLED_NEW = 0x00000001,
|
||||
|
||||
/// <summary>The top-level name trust record is disabled by the domain administrator.<note type="note">This flag MUST be used only
|
||||
/// with forest trust record types of ForestTrustTopLevelName and ForestTrustTopLevelNameEx.</note></summary>
|
||||
/// <summary>
|
||||
/// The top-level name trust record is disabled by the domain administrator. <note type="note">This flag MUST be used only with
|
||||
/// forest trust record types of ForestTrustTopLevelName and ForestTrustTopLevelNameEx.</note>
|
||||
/// </summary>
|
||||
LSA_TLN_DISABLED_ADMIN = 0x00000002,
|
||||
|
||||
/// <summary>The top-level name trust record is disabled due to a conflict.<note type="note">This flag MUST be used only with
|
||||
/// forest trust record types of ForestTrustTopLevelName and ForestTrustTopLevelNameEx.</note></summary>
|
||||
/// <summary>
|
||||
/// The top-level name trust record is disabled due to a conflict. <note type="note">This flag MUST be used only with forest
|
||||
/// trust record types of ForestTrustTopLevelName and ForestTrustTopLevelNameEx.</note>
|
||||
/// </summary>
|
||||
LSA_TLN_DISABLED_CONFLICT = 0x00000004,
|
||||
|
||||
/// <summary>The domain information trust record is disabled by the domain administrator.<note type="note">This flag MUST be used
|
||||
/// only with a forest trust record type of ForestTrustDomainInfo.</note></summary>
|
||||
/// <summary>
|
||||
/// The domain information trust record is disabled by the domain administrator. <note type="note">This flag MUST be used only
|
||||
/// with a forest trust record type of ForestTrustDomainInfo.</note>
|
||||
/// </summary>
|
||||
LSA_SID_DISABLED_ADMIN = 0x00000001,
|
||||
|
||||
/// <summary>The domain information trust record is disabled due to a conflict.<note type="note">This flag MUST be used only with
|
||||
/// a forest trust record type of ForestTrustDomainInfo.</note></summary>
|
||||
/// <summary>
|
||||
/// The domain information trust record is disabled due to a conflict. <note type="note">This flag MUST be used only with a
|
||||
/// forest trust record type of ForestTrustDomainInfo.</note>
|
||||
/// </summary>
|
||||
LSA_SID_DISABLED_CONFLICT = 0x00000002,
|
||||
|
||||
/// <summary>The domain information trust record is disabled by the domain administrator.<note type="note">This flag MUST be used
|
||||
/// only with a forest trust record type of ForestTrustDomainInfo.</note></summary>
|
||||
/// <summary>
|
||||
/// The domain information trust record is disabled by the domain administrator. <note type="note">This flag MUST be used only
|
||||
/// with a forest trust record type of ForestTrustDomainInfo.</note>
|
||||
/// </summary>
|
||||
LSA_NB_DISABLED_ADMIN = 0x00000004,
|
||||
|
||||
/// <summary>The domain information trust record is disabled due to a conflict.<note type="note">This flag MUST be used only with
|
||||
/// a forest trust record type of ForestTrustDomainInfo.</note></summary>
|
||||
/// <summary>
|
||||
/// The domain information trust record is disabled due to a conflict. <note type="note">This flag MUST be used only with a
|
||||
/// forest trust record type of ForestTrustDomainInfo.</note>
|
||||
/// </summary>
|
||||
LSA_NB_DISABLED_CONFLICT = 0x00000008,
|
||||
|
||||
/// <summary>The domain information trust record is disabled.<note type="note">This set of flags is reserved; for current and
|
||||
/// future reasons, the trust is disabled.</note></summary>
|
||||
/// <summary>
|
||||
/// The domain information trust record is disabled. <note type="note">This set of flags is reserved; for current and future
|
||||
/// reasons, the trust is disabled.</note>
|
||||
/// </summary>
|
||||
LSA_FTRECORD_DISABLED_REASONS = 0x0000FFFF,
|
||||
}
|
||||
|
||||
|
@ -208,32 +224,48 @@ namespace Vanara.PInvoke
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// The LsaAddAccountRights function assigns one or more privileges to an account. If the account does not exist, LsaAddAccountRights
|
||||
/// creates it.
|
||||
/// The <c>LsaAddAccountRights</c> function assigns one or more privileges to an account. If the account does not exist,
|
||||
/// <c>LsaAddAccountRights</c> creates it.
|
||||
/// </summary>
|
||||
/// <param name="PolicyHandle">
|
||||
/// A handle to a Policy object. The handle must have the POLICY_LOOKUP_NAMES access right. If the account identified by the
|
||||
/// AccountSid parameter does not exist, the handle must have the POLICY_CREATE_ACCOUNT access right. For more information, see
|
||||
/// Opening a Policy Object Handle.
|
||||
/// </param>
|
||||
/// <param name="pSID">Pointer to the SID of the account to which the function assigns privileges.</param>
|
||||
/// <param name="AccountSid">Pointer to the SID of the account to which the function assigns privileges.</param>
|
||||
/// <param name="UserRights">
|
||||
/// Pointer to an array of strings. Each string contains the name of a privilege to add to the account. For a list of privilege
|
||||
/// names, see Privilege Constants.
|
||||
/// Pointer to an array of LSA_UNICODE_STRING structures. Each structure contains the name of a privilege to add to the account. For
|
||||
/// a list of privilege names, see Privilege Constants.
|
||||
/// </param>
|
||||
/// <param name="CountOfRights">Specifies the number of elements in the UserRights array.</param>
|
||||
/// <returns>
|
||||
/// If the function succeeds, the return value is STATUS_SUCCESS. If the function fails, the return value is an NTSTATUS code, which
|
||||
/// can be the following value or one of the LSA Policy Function Return Values.
|
||||
/// <para>If the function succeeds, the return value is STATUS_SUCCESS.</para>
|
||||
/// <para>
|
||||
/// If the function fails, the return value is an NTSTATUS code, which can be the following value or one of the LSA Policy Function
|
||||
/// Return Values.
|
||||
/// </para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Return code</term>
|
||||
/// <term>Description</term>
|
||||
/// </listheader>
|
||||
/// <item>
|
||||
/// <term>STATUS_NO_SUCH_PRIVILEGE</term>
|
||||
/// <term>One of the privilege names is not valid.</term>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// <para>You can use the LsaNtStatusToWinError function to convert the NTSTATUS code to a Windows error code.</para>
|
||||
/// </returns>
|
||||
[DllImport(Lib.AdvApi32, ExactSpelling = true), SuppressUnmanagedCodeSecurity]
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "ms721786")]
|
||||
public static extern uint LsaAddAccountRights(
|
||||
LSA_HANDLE PolicyHandle,
|
||||
PSID pSID,
|
||||
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))]
|
||||
string[] UserRights,
|
||||
int CountOfRights);
|
||||
/// <remarks>
|
||||
/// <para>If you specify privileges already granted to the account, they are ignored.</para>
|
||||
/// <para>For an example that demonstrates calling this function, see Managing Account Permissions.</para>
|
||||
/// </remarks>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsaaddaccountrights NTSTATUS LsaAddAccountRights(
|
||||
// LSA_HANDLE PolicyHandle, PSID AccountSid, PLSA_UNICODE_STRING UserRights, ULONG CountOfRights );
|
||||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "66b78404-02c2-48e9-92c3-d27b68f77c23")]
|
||||
public static extern NTStatus LsaAddAccountRights(LSA_HANDLE PolicyHandle, PSID AccountSid,
|
||||
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))] string[] UserRights, uint CountOfRights);
|
||||
|
||||
/// <summary>Undocumented function for creating an account.</summary>
|
||||
/// <param name="PolicyHandle">A handle to a Policy object. For more information, see Opening a Policy Object Handle.</param>
|
||||
|
@ -247,7 +279,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("ntlsa.h")]
|
||||
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
|
||||
public static extern uint LsaCreateAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LsaAccountAccessMask DesiredAccess, out SafeLSA_HANDLE AccountHandle);
|
||||
public static extern NTStatus LsaCreateAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LsaAccountAccessMask DesiredAccess, out SafeLSA_HANDLE AccountHandle);
|
||||
|
||||
/// <summary>The <c>LsaCreateTrustedDomainEx</c> function establishes a new trusted domain by creating a new TrustedDomain object.</summary>
|
||||
/// <param name="PolicyHandle">
|
||||
|
@ -356,7 +388,7 @@ namespace Vanara.PInvoke
|
|||
// LsaEnumerateAccountRights( LSA_HANDLE PolicyHandle, PSID AccountSid, PLSA_UNICODE_STRING *UserRights, PULONG CountOfRights );
|
||||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "3f4a4a9a-66ca-410a-8bdc-c390e8b966e3")]
|
||||
public static extern uint LsaEnumerateAccountRights(
|
||||
public static extern NTStatus LsaEnumerateAccountRights(
|
||||
LSA_HANDLE PolicyHandle,
|
||||
PSID AccountSid,
|
||||
out SafeLsaMemoryHandle UserRights,
|
||||
|
@ -377,7 +409,7 @@ namespace Vanara.PInvoke
|
|||
var winErr = LsaNtStatusToWinError(ret);
|
||||
if (winErr == Win32Error.ERROR_FILE_NOT_FOUND) return new string[0];
|
||||
winErr.ThrowIfFailed();
|
||||
return mem.DangerousGetHandle().ToIEnum<LSA_UNICODE_STRING>((int)cnt).Select(u => (string)u.ToString().Clone());
|
||||
return mem.DangerousGetHandle().ToIEnum<LSA_UNICODE_STRING>((int)cnt).Select(u => (string)u.ToString().Clone()).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -441,9 +473,9 @@ namespace Vanara.PInvoke
|
|||
[PInvokeData("ntsecapi.h", MSDNShortId = "97e7180e-4edb-4edd-915e-0477e7e7a9ff")]
|
||||
// public static extern NTSTATUS LsaEnumerateAccountsWithUserRight(LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING UserRight, ref IntPtr
|
||||
// Buffer, ref uint CountReturned);
|
||||
public static extern uint LsaEnumerateAccountsWithUserRight(
|
||||
public static extern NTStatus LsaEnumerateAccountsWithUserRight(
|
||||
LSA_HANDLE PolicyHandle,
|
||||
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string UserRight,
|
||||
[In, Optional, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string UserRight,
|
||||
out SafeLsaMemoryHandle Buffer,
|
||||
out int CountReturned);
|
||||
|
||||
|
@ -463,13 +495,12 @@ namespace Vanara.PInvoke
|
|||
/// </para>
|
||||
/// </param>
|
||||
/// <returns>An enumeration of security identifiers (SID) of accounts that holds the specified privilege.</returns>
|
||||
public static IEnumerable<PSID> LsaEnumerateAccountsWithUserRight(LSA_HANDLE PolicyHandle, string UserRights)
|
||||
public static IEnumerable<PSID> LsaEnumerateAccountsWithUserRight(LSA_HANDLE PolicyHandle, [Optional] string UserRights)
|
||||
{
|
||||
var ret = LsaEnumerateAccountsWithUserRight(PolicyHandle, UserRights, out var mem, out var cnt);
|
||||
if (ret == NTStatus.STATUS_NO_MORE_ENTRIES) return new PSID[0];
|
||||
var wret = LsaNtStatusToWinError(ret);
|
||||
wret.ThrowIfFailed();
|
||||
return mem.DangerousGetHandle().ToIEnum<LSA_ENUMERATION_INFORMATION>(cnt).Select(u => u.Sid);
|
||||
LsaNtStatusToWinError(ret).ThrowIfFailed();
|
||||
return mem.DangerousGetHandle().ToIEnum<LSA_ENUMERATION_INFORMATION>(cnt).Select(u => u.Sid).ToArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -695,15 +726,13 @@ namespace Vanara.PInvoke
|
|||
[PInvokeData("ntsecapi.h", MSDNShortId = "4a203bff-c3e1-4d95-b556-617dc8c2e8c2")]
|
||||
public static extern NTStatus LsaEnumerateTrustedDomainsEx(LSA_HANDLE PolicyHandle, ref LSA_ENUMERATION_HANDLE EnumerationContext, out SafeLsaMemoryHandle Buffer, uint PreferedMaximumLength, out uint CountReturned);
|
||||
|
||||
/// <summary>Gets system access for an account.</summary>
|
||||
/// <summary>[Undocumented] Gets system access for an account.</summary>
|
||||
/// <param name="AccountHandle">The account handle.</param>
|
||||
/// <param name="SystemAccess">The system access.</param>
|
||||
/// <returns>
|
||||
/// <para>If the function succeeds, the function returns one of the following <c>NTSTATUS</c> values.</para>
|
||||
/// </returns>
|
||||
/// <returns>If the function succeeds, the function returns one of the following <c>NTSTATUS</c> values.</returns>
|
||||
[PInvokeData("ntlsa.h")]
|
||||
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
|
||||
public static extern uint LsaGetSystemAccessAccount(LSA_HANDLE AccountHandle, out int SystemAccess);
|
||||
public static extern NTStatus LsaGetSystemAccessAccount(LSA_HANDLE AccountHandle, out int SystemAccess);
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
|
@ -1276,34 +1305,29 @@ namespace Vanara.PInvoke
|
|||
// PLSA_REFERENCED_DOMAIN_LIST ReferencedDomains, ref PLSA_TRANSLATED_NAME Names);
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "6B30D1FF-35DC-44E8-A765-36A5761EC0CE")]
|
||||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Unicode)]
|
||||
public static extern uint LsaLookupSids2(
|
||||
public static extern NTStatus LsaLookupSids2(
|
||||
LSA_HANDLE PolicyHandle,
|
||||
LsaLookupSidsFlags LookupOptions,
|
||||
uint Count,
|
||||
[In, MarshalAs(UnmanagedType.LPArray)] IntPtr[] Sids,
|
||||
[In, MarshalAs(UnmanagedType.LPArray)] PSID[] Sids,
|
||||
out SafeLsaMemoryHandle ReferencedDomains,
|
||||
out SafeLsaMemoryHandle Names);
|
||||
|
||||
/// <summary>
|
||||
/// <para>The <c>LsaNtStatusToWinError</c> function converts an NTSTATUS code returned by an LSA function to a Windows error code.</para>
|
||||
/// The <c>LsaNtStatusToWinError</c> function converts an NTSTATUS code returned by an LSA function to a Windows error code.
|
||||
/// </summary>
|
||||
/// <param name="Status">
|
||||
/// <para>An NTSTATUS code returned by an LSA function call. This value will be converted to a System error code.</para>
|
||||
/// </param>
|
||||
/// <param name="Status">An NTSTATUS code returned by an LSA function call. This value will be converted to a System error code.</param>
|
||||
/// <returns>
|
||||
/// <para>
|
||||
/// The return value is the Windows error code that corresponds to the Status parameter. If there is no corresponding Windows error
|
||||
/// code, the return value is ERROR_MR_MID_NOT_FOUND.
|
||||
/// </para>
|
||||
/// </returns>
|
||||
// https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsantstatustowinerror ULONG LsaNtStatusToWinError(
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/nf-ntsecapi-lsantstatustowinerror ULONG LsaNtStatusToWinError(
|
||||
// NTSTATUS Status );
|
||||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "fa91794c-c502-4b36-84cc-a8d77c8e9d9f")]
|
||||
// public static extern uint LsaNtStatusToWinError(NTSTATUS Status);
|
||||
public static extern Win32Error LsaNtStatusToWinError(uint Status);
|
||||
public static extern Win32Error LsaNtStatusToWinError(NTStatus Status);
|
||||
|
||||
/// <summary>Undocumented. Opens an account.</summary>
|
||||
/// <summary>[Undocumented] Opens an account.</summary>
|
||||
/// <param name="PolicyHandle">The policy handle.</param>
|
||||
/// <param name="AccountSid">The account sid.</param>
|
||||
/// <param name="DesiredAccess">The desired access.</param>
|
||||
|
@ -1311,7 +1335,7 @@ namespace Vanara.PInvoke
|
|||
/// <returns>NTSTATUS</returns>
|
||||
[PInvokeData("ntlsa.h")]
|
||||
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
|
||||
public static extern uint LsaOpenAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LsaAccountAccessMask DesiredAccess, out SafeLSA_HANDLE AccountHandle);
|
||||
public static extern NTStatus LsaOpenAccount(LSA_HANDLE PolicyHandle, PSID AccountSid, LsaAccountAccessMask DesiredAccess, out SafeLSA_HANDLE AccountHandle);
|
||||
|
||||
/// <summary>
|
||||
/// <para>The <c>LsaOpenPolicy</c> function opens a handle to the Policy object on a local or remote system.</para>
|
||||
|
@ -1360,9 +1384,9 @@ namespace Vanara.PInvoke
|
|||
[PInvokeData("ntsecapi.h", MSDNShortId = "361bc962-1e97-4606-a835-cbce37692c55")]
|
||||
// public static extern NTSTATUS LsaOpenPolicy(PLSA_UNICODE_STRING SystemName, PLSA_OBJECT_ATTRIBUTES ObjectAttributes, ACCESS_MASK
|
||||
// DesiredAccess, PLSA_HANDLE PolicyHandle);
|
||||
public static extern uint LsaOpenPolicy(
|
||||
public static extern NTStatus LsaOpenPolicy(
|
||||
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string SystemName,
|
||||
ref LSA_OBJECT_ATTRIBUTES ObjectAttributes,
|
||||
in LSA_OBJECT_ATTRIBUTES ObjectAttributes,
|
||||
LsaPolicyRights DesiredAccess,
|
||||
out SafeLSA_HANDLE PolicyHandle);
|
||||
|
||||
|
@ -1380,10 +1404,10 @@ namespace Vanara.PInvoke
|
|||
/// opens the Policy object on the local system.
|
||||
/// </param>
|
||||
/// <returns>A pointer to an LSA_HANDLE variable that receives a handle to the Policy object.</returns>
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "361bc962-1e97-4606-a835-cbce37692c55")]
|
||||
public static SafeLSA_HANDLE LsaOpenPolicy(LsaPolicyRights DesiredAccess, string SystemName = null)
|
||||
{
|
||||
var oa = LSA_OBJECT_ATTRIBUTES.Empty;
|
||||
LsaNtStatusToWinError(LsaOpenPolicy(SystemName, ref oa, DesiredAccess, out var handle)).ThrowIfFailed();
|
||||
LsaNtStatusToWinError(LsaOpenPolicy(SystemName, LSA_OBJECT_ATTRIBUTES.Empty, DesiredAccess, out var handle)).ThrowIfFailed();
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -1484,7 +1508,7 @@ namespace Vanara.PInvoke
|
|||
// LsaQueryDomainInformationPolicy( LSA_HANDLE PolicyHandle, POLICY_DOMAIN_INFORMATION_CLASS InformationClass, PVOID *Buffer );
|
||||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "39a511d7-46fc-4d12-ba43-771f6db2a33b")]
|
||||
public static extern NTStatus LsaQueryDomainInformationPolicy(LSA_HANDLE PolicyHandle, POLICY_DOMAIN_INFORMATION_CLASS InformationClass, out IntPtr Buffer);
|
||||
public static extern NTStatus LsaQueryDomainInformationPolicy(LSA_HANDLE PolicyHandle, POLICY_DOMAIN_INFORMATION_CLASS InformationClass, out SafeLsaMemoryHandle Buffer);
|
||||
|
||||
/// <summary>
|
||||
/// The <c>LsaQueryForestTrustInformation</c> function retrieves forest trust information for the specified Local Security Authority
|
||||
|
@ -1839,13 +1863,13 @@ namespace Vanara.PInvoke
|
|||
[PInvokeData("ntsecapi.h", MSDNShortId = "ad250a01-7a24-4fae-975c-aa3e65731c82")]
|
||||
// public static extern NTSTATUS LsaRemoveAccountRights(LSA_HANDLE PolicyHandle, PSID AccountSid, [MarshalAs(UnmanagedType.U1)] bool
|
||||
// AllRights, PLSA_UNICODE_STRING UserRights, uint CountOfRights);
|
||||
public static extern uint LsaRemoveAccountRights(
|
||||
public static extern NTStatus LsaRemoveAccountRights(
|
||||
LSA_HANDLE PolicyHandle,
|
||||
PSID AccountSid,
|
||||
[MarshalAs(UnmanagedType.Bool)] bool AllRights,
|
||||
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringArrayMarshaler))]
|
||||
string[] UserRights,
|
||||
int CountOfRights);
|
||||
uint CountOfRights);
|
||||
|
||||
/// <summary>Do not use the LSA private data functions. Instead, use the CryptProtectData and CryptUnprotectData functions.</summary>
|
||||
/// <param name="PolicyHandle">
|
||||
|
@ -1905,7 +1929,10 @@ namespace Vanara.PInvoke
|
|||
// LSA_HANDLE PolicyHandle, PLSA_UNICODE_STRING KeyName, PLSA_UNICODE_STRING *PrivateData );
|
||||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "005460db-0919-46eb-b057-37c5b6042243")]
|
||||
public static extern NTStatus LsaRetrievePrivateData(LSA_HANDLE PolicyHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string KeyName, [Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] out string PrivateData);
|
||||
public static extern NTStatus LsaRetrievePrivateData(LSA_HANDLE PolicyHandle, [In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] string KeyName,
|
||||
out SafeLsaMemoryHandle PrivateData);
|
||||
|
||||
//[Out, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(LsaUnicodeStringMarshaler))] out string PrivateData);
|
||||
|
||||
/// <summary>The <c>LsaSetDomainInformationPolicy</c> function sets domain information to the Policyobject.</summary>
|
||||
/// <param name="PolicyHandle">A handle to the Policy object for the system.</param>
|
||||
|
@ -2098,7 +2125,7 @@ namespace Vanara.PInvoke
|
|||
/// </returns>
|
||||
[PInvokeData("ntlsa.h")]
|
||||
[DllImport(Lib.AdvApi32, ExactSpelling = true)]
|
||||
public static extern uint LsaSetSystemAccessAccount(LSA_HANDLE AccountHandle, int SystemAccess);
|
||||
public static extern NTStatus LsaSetSystemAccessAccount(LSA_HANDLE AccountHandle, int SystemAccess);
|
||||
|
||||
/// <summary>The <c>LsaSetTrustedDomainInfoByName</c> function sets values for a TrustedDomain object.</summary>
|
||||
/// <param name="PolicyHandle">
|
||||
|
@ -2293,7 +2320,7 @@ namespace Vanara.PInvoke
|
|||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "6283b1da-4ec3-48e1-91f6-321c6390befe")]
|
||||
// public static extern NTSTATUS LsaClose(LSA_HANDLE ObjectHandle);
|
||||
private static extern uint LsaClose(LSA_HANDLE ObjectHandle);
|
||||
private static extern NTStatus LsaClose(LSA_HANDLE ObjectHandle);
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
|
@ -2329,13 +2356,13 @@ namespace Vanara.PInvoke
|
|||
[DllImport(Lib.AdvApi32, SetLastError = false, ExactSpelling = true)]
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "6eb3d18f-c54c-4e51-8a4b-b7a3f930cfa9")]
|
||||
// public static extern NTSTATUS LsaFreeMemory(IntPtr Buffer);
|
||||
private static extern uint LsaFreeMemory(IntPtr Buffer);
|
||||
private static extern NTStatus LsaFreeMemory(IntPtr Buffer);
|
||||
|
||||
/// <summary>Provides a handle to an LSA enumeration.</summary>
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LSA_ENUMERATION_HANDLE : IHandle
|
||||
{
|
||||
private IntPtr handle;
|
||||
private readonly IntPtr handle;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="LSA_ENUMERATION_HANDLE"/> struct.</summary>
|
||||
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
|
||||
|
@ -2599,7 +2626,7 @@ namespace Vanara.PInvoke
|
|||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct LSA_HANDLE : IHandle
|
||||
{
|
||||
private IntPtr handle;
|
||||
private readonly IntPtr handle;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="LSA_HANDLE"/> struct.</summary>
|
||||
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
|
||||
|
@ -2733,7 +2760,7 @@ namespace Vanara.PInvoke
|
|||
public LSA_UNICODE_STRING Name;
|
||||
|
||||
/// <summary>Pointer to the SID of the domain.</summary>
|
||||
public IntPtr Sid;
|
||||
public PSID Sid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -2762,7 +2789,7 @@ namespace Vanara.PInvoke
|
|||
public StrPtrUni Buffer;
|
||||
|
||||
/* REMOVED TO AVOID MEMORY LEAK
|
||||
*
|
||||
*
|
||||
/// <summary>Initializes a new instance of the <see cref="LSA_UNICODE_STRING"/> struct from a string.</summary>
|
||||
/// <param name="s">The string value.</param>
|
||||
/// <exception cref="System.ArgumentException">String exceeds 32Kb of data.</exception>
|
||||
|
@ -2796,7 +2823,7 @@ namespace Vanara.PInvoke
|
|||
/// <summary>Performs an implicit conversion from <see cref="LSA_UNICODE_STRING"/> to <see cref="string"/>.</summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator string(LSA_UNICODE_STRING value) => (string)value.Buffer;
|
||||
public static implicit operator string(LSA_UNICODE_STRING value) => value.Buffer;
|
||||
}
|
||||
|
||||
/// <summary>Smart wrapper for LSA_FOREST_TRUST_INFORMATION.</summary>
|
||||
|
@ -2925,7 +2952,9 @@ namespace Vanara.PInvoke
|
|||
Excluded = exclude;
|
||||
}
|
||||
|
||||
/// <summary>Gets or sets a value indicating whether this <see cref="LsaForestTrustTopLevelName"/> contains an excluded top-level name..</summary>
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="LsaForestTrustTopLevelName"/> contains an excluded top-level name..
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if excluded; otherwise, <c>false</c> to include.</value>
|
||||
public bool Excluded { get; set; }
|
||||
|
||||
|
@ -2965,29 +2994,37 @@ namespace Vanara.PInvoke
|
|||
public static implicit operator LSA_HANDLE(SafeLSA_HANDLE h) => h.handle;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool InternalReleaseHandle() => LsaClose(this) == 0;
|
||||
protected override bool InternalReleaseHandle() => LsaClose(this).Succeeded;
|
||||
}
|
||||
|
||||
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="LSA_UNICODE_STRING"/> that manages its own memory allocations.</summary>
|
||||
public class SafeLSA_UNICODE_STRING : SafeHANDLE
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SafeLSA_UNICODE_STRING"/> class.
|
||||
/// </summary>
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeLSA_UNICODE_STRING"/> class.</summary>
|
||||
/// <param name="value">The value of the string to assign.</param>
|
||||
public SafeLSA_UNICODE_STRING(string value) : base(IntPtr.Zero, true)
|
||||
{
|
||||
Buffer = value;
|
||||
}
|
||||
public SafeLSA_UNICODE_STRING(string value) : base(IntPtr.Zero, true) => Buffer = value;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeLSA_UNICODE_STRING"/> class and assigns an existing handle.</summary>
|
||||
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
|
||||
/// <param name="ownsHandle"><see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).</param>
|
||||
/// <param name="ownsHandle">
|
||||
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
|
||||
/// </param>
|
||||
public SafeLSA_UNICODE_STRING(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeLSA_UNICODE_STRING"/> class.</summary>
|
||||
private SafeLSA_UNICODE_STRING() : base() { }
|
||||
|
||||
/// <summary>The string value.</summary>
|
||||
public string Buffer
|
||||
{
|
||||
get => LsaUnicodeStringMarshaler.MarshalPtr(handle);
|
||||
set
|
||||
{
|
||||
Close();
|
||||
SetHandle(LsaUnicodeStringMarshaler.MarshalValue(value));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the length, in bytes, of the string pointed to by the Buffer member, not including the terminating null character,
|
||||
/// if any.
|
||||
|
@ -3000,32 +3037,21 @@ namespace Vanara.PInvoke
|
|||
/// </summary>
|
||||
public short MaximumLength => IsInvalid ? (short)0 : Marshal.ReadInt16(handle, 2);
|
||||
|
||||
/// <summary>The string value.</summary>
|
||||
public string Buffer
|
||||
{
|
||||
get => LsaUnicodeStringMarshaler.MarshalPtr(handle);
|
||||
set
|
||||
{
|
||||
Close();
|
||||
SetHandle(LsaUnicodeStringMarshaler.MarshalValue(value));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="SafeLSA_UNICODE_STRING"/> to <see cref="LSA_UNICODE_STRING"/>.</summary>
|
||||
/// <param name="h">The safe handle instance.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator LSA_UNICODE_STRING(SafeLSA_UNICODE_STRING h) => h.handle.ToStructure<LSA_UNICODE_STRING>();
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="SafeLSA_UNICODE_STRING"/> to <see cref="System.String"/>.</summary>
|
||||
/// <param name="h">The <see cref="SafeLSA_UNICODE_STRING"/> instance.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator string(SafeLSA_UNICODE_STRING h) => h.Buffer;
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="System.String"/> to <see cref="SafeLSA_UNICODE_STRING"/>.</summary>
|
||||
/// <param name="val">The string value.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator SafeLSA_UNICODE_STRING(string val) => new SafeLSA_UNICODE_STRING(val);
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="SafeLSA_UNICODE_STRING"/> to <see cref="System.String"/>.</summary>
|
||||
/// <param name="h">The <see cref="SafeLSA_UNICODE_STRING"/> instance.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator string(SafeLSA_UNICODE_STRING h) => h.Buffer;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool InternalReleaseHandle()
|
||||
{
|
||||
|
@ -3051,7 +3077,7 @@ namespace Vanara.PInvoke
|
|||
private SafeLsaMemoryHandle() : base() { }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool InternalReleaseHandle() => LsaFreeMemory(handle) == 0;
|
||||
protected override bool InternalReleaseHandle() => LsaFreeMemory(handle).Succeeded;
|
||||
}
|
||||
|
||||
/// <summary>Base class for other LSA memory handles.</summary>
|
||||
|
@ -3098,7 +3124,9 @@ namespace Vanara.PInvoke
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>A <see cref="SafeHandle"/> for values that must be freed using the <see cref="Secur32.LsaFreeReturnBuffer(IntPtr)"/> function.</summary>
|
||||
/// <summary>
|
||||
/// A <see cref="SafeHandle"/> for values that must be freed using the <see cref="Secur32.LsaFreeReturnBuffer(IntPtr)"/> function.
|
||||
/// </summary>
|
||||
public sealed class SafeLsaReturnBufferHandle : SafeLsaMemoryHandleBase
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeLsaReturnBufferHandle"/> class.</summary>
|
||||
|
@ -3140,7 +3168,7 @@ namespace Vanara.PInvoke
|
|||
var strSz = uma.Sum(s => s.length + 2);
|
||||
var result = Marshal.AllocCoTaskMem(sz * a.Length + strSz);
|
||||
var strPtr = result.Offset(sz * a.Length);
|
||||
for (int i = 0; i < uma.Length; i++)
|
||||
for (var i = 0; i < uma.Length; i++)
|
||||
{
|
||||
uma[i].Buffer = strPtr;
|
||||
StringHelper.Write(a[i], (IntPtr)uma[i].Buffer, out var byteCnt, true, CharSet.Unicode);
|
||||
|
@ -3187,6 +3215,8 @@ namespace Vanara.PInvoke
|
|||
return s;
|
||||
}
|
||||
|
||||
internal static string MarshalPtr(IntPtr ptr) => ptr == IntPtr.Zero ? null : StringHelper.GetString(ptr.Offset(4), CharSet.Unicode, Marshal.ReadInt16(ptr));
|
||||
|
||||
internal static IntPtr MarshalValue(string value)
|
||||
{
|
||||
if (value is null) return IntPtr.Zero;
|
||||
|
@ -3204,8 +3234,6 @@ namespace Vanara.PInvoke
|
|||
}
|
||||
return mem;
|
||||
}
|
||||
|
||||
internal static string MarshalPtr(IntPtr ptr) => ptr == IntPtr.Zero ? null : StringHelper.GetString(ptr.Offset(4), CharSet.Unicode, Marshal.ReadInt16(ptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +1,5 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using System.Text;
|
||||
using Vanara.Extensions;
|
||||
using Vanara.InteropServices;
|
||||
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
|
||||
|
||||
|
@ -21,12 +16,15 @@ namespace Vanara.PInvoke
|
|||
public enum POLICY_DOMAIN_INFORMATION_CLASS
|
||||
{
|
||||
/// <summary/>
|
||||
[CorrespondingType(typeof(POLICY_DOMAIN_QUALITY_OF_SERVICE_INFO), CorrespondingAction.Set)]
|
||||
PolicyDomainQualityOfServiceInformation = 1,
|
||||
|
||||
/// <summary>The information is for Encrypting File System.</summary>
|
||||
[CorrespondingType(typeof(POLICY_DOMAIN_EFS_INFO))]
|
||||
PolicyDomainEfsInformation,
|
||||
|
||||
/// <summary>The information is for a Kerberos ticket.</summary>
|
||||
[CorrespondingType(typeof(POLICY_DOMAIN_KERBEROS_TICKET_INFO))]
|
||||
PolicyDomainKerberosTicketInformation,
|
||||
}
|
||||
|
||||
|
@ -43,47 +41,59 @@ namespace Vanara.PInvoke
|
|||
public enum POLICY_INFORMATION_CLASS
|
||||
{
|
||||
/// <summary>This value is obsolete.</summary>
|
||||
[Obsolete]
|
||||
PolicyAuditLogInformation = 1,
|
||||
|
||||
/// <summary>
|
||||
/// Query or set the auditing rules of the system. You can enable or disable auditing and specify the types of events that are
|
||||
/// audited. Use the POLICY_AUDIT_EVENTS_INFO structure.
|
||||
/// </summary>
|
||||
[CorrespondingType(typeof(POLICY_AUDIT_EVENTS_INFO))]
|
||||
PolicyAuditEventsInformation,
|
||||
|
||||
/// <summary>This value is obsolete. Use the PolicyDnsDomainInformation value instead.</summary>
|
||||
[Obsolete]
|
||||
PolicyPrimaryDomainInformation,
|
||||
|
||||
/// <summary>This value is obsolete.</summary>
|
||||
[Obsolete]
|
||||
PolicyPdAccountInformation,
|
||||
|
||||
/// <summary>Query or set the name and SID of the account domain of the system. Use the POLICY_ACCOUNT_DOMAIN_INFO structure.</summary>
|
||||
[CorrespondingType(typeof(POLICY_ACCOUNT_DOMAIN_INFO))]
|
||||
PolicyAccountDomainInformation,
|
||||
|
||||
/// <summary>Query or set the role of an LSA server. Use the POLICY_LSA_SERVER_ROLE_INFO structure.</summary>
|
||||
[CorrespondingType(typeof(POLICY_LSA_SERVER_ROLE_INFO))]
|
||||
PolicyLsaServerRoleInformation,
|
||||
|
||||
/// <summary>This value is obsolete.</summary>
|
||||
[Obsolete]
|
||||
PolicyReplicaSourceInformation,
|
||||
|
||||
/// <summary>This value is obsolete.</summary>
|
||||
[Obsolete]
|
||||
PolicyDefaultQuotaInformation,
|
||||
|
||||
/// <summary>
|
||||
/// Query or set information about the creation time and last modification of the LSA database. Use the POLICY_MODIFICATION_INFO structure.
|
||||
/// </summary>
|
||||
[CorrespondingType(typeof(POLICY_MODIFICATION_INFO))]
|
||||
PolicyModificationInformation,
|
||||
|
||||
/// <summary>This value is obsolete.</summary>
|
||||
[Obsolete]
|
||||
PolicyAuditFullSetInformation,
|
||||
|
||||
/// <summary>This value is obsolete.</summary>
|
||||
[Obsolete]
|
||||
PolicyAuditFullQueryInformation,
|
||||
|
||||
/// <summary>
|
||||
/// Query or set Domain Name System (DNS) information about the account domain associated with a Policy object. Use the
|
||||
/// POLICY_DNS_DOMAIN_INFO structure.
|
||||
/// </summary>
|
||||
[CorrespondingType(typeof(POLICY_DNS_DOMAIN_INFO))]
|
||||
PolicyDnsDomainInformation,
|
||||
|
||||
/// <summary/>
|
||||
|
@ -96,6 +106,53 @@ namespace Vanara.PInvoke
|
|||
PolicyMachineAccountInformation,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <c>POLICY_LSA_SERVER_ROLE</c> enumeration type defines values that indicate the role of an LSA server. The
|
||||
/// LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this enumeration type when their InformationClass parameters
|
||||
/// are set to <c>PolicyLsaServerRoleInformation</c>.
|
||||
/// </summary>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ne-ntsecapi-policy_lsa_server_role typedef enum
|
||||
// _POLICY_LSA_SERVER_ROLE { PolicyServerRoleBackup, PolicyServerRolePrimary } POLICY_LSA_SERVER_ROLE, *PPOLICY_LSA_SERVER_ROLE;
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "a2bcc380-8873-436b-a0d6-e4deb23669bb")]
|
||||
public enum POLICY_LSA_SERVER_ROLE
|
||||
{
|
||||
/// <summary>Indicates a backup LSA server.</summary>
|
||||
PolicyServerRoleBackup = 2,
|
||||
|
||||
/// <summary>Indicates a primary LSA server, a workstation, or a standalone computer.</summary>
|
||||
PolicyServerRolePrimary,
|
||||
}
|
||||
|
||||
/// <summary>[Undocumented] Used by POLICY_DOMAIN_QUALITY_OF_SERVICE_INFO.</summary>
|
||||
[PInvokeData("ntsecapi.h")]
|
||||
public enum POLICY_QOS : uint
|
||||
{
|
||||
POLICY_QOS_SCHANNEL_REQUIRED = 0x00000001,
|
||||
POLICY_QOS_OUTBOUND_INTEGRITY = 0x00000002,
|
||||
POLICY_QOS_OUTBOUND_CONFIDENTIALITY = 0x00000004,
|
||||
POLICY_QOS_INBOUND_INTEGRITY = 0x00000008,
|
||||
POLICY_QOS_INBOUND_CONFIDENTIALITY = 0x00000010,
|
||||
POLICY_QOS_ALLOW_LOCAL_ROOT_CERT_STORE = 0x00000020,
|
||||
POLICY_QOS_RAS_SERVER_ALLOWED = 0x00000040,
|
||||
POLICY_QOS_DHCP_SERVER_ALLOWED = 0x00000080,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <c>POLICY_SERVER_ENABLE_STATE</c> enumeration represents the state of the LSA server—that is, whether it is enabled or
|
||||
/// disabled. Some operations may only be performed on an enabled LSA server.
|
||||
/// </summary>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ne-ntsecapi-policy_server_enable_state typedef enum
|
||||
// _POLICY_SERVER_ENABLE_STATE { PolicyServerEnabled, PolicyServerDisabled } POLICY_SERVER_ENABLE_STATE, *PPOLICY_SERVER_ENABLE_STATE;
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "aae5875e-ca55-4571-a9a4-684280ae8aa0")]
|
||||
public enum POLICY_SERVER_ENABLE_STATE
|
||||
{
|
||||
/// <summary>The LSA server is enabled.</summary>
|
||||
PolicyServerEnabled = 2,
|
||||
|
||||
/// <summary>The LSA server is disabled.</summary>
|
||||
PolicyServerDisabled,
|
||||
}
|
||||
|
||||
/// <summary>Indicates the attributes of a trust relationship.</summary>
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "acf9a2b5-f301-4e6a-a515-df338658ad56")]
|
||||
[Flags]
|
||||
|
@ -179,7 +236,7 @@ namespace Vanara.PInvoke
|
|||
{
|
||||
/// <summary>Query or set the name of a trusted domain. Use the TRUSTED_DOMAIN_NAME_INFO structure.</summary>
|
||||
[CorrespondingType(typeof(TRUSTED_DOMAIN_NAME_INFO))]
|
||||
TrustedDomainNameInformation,
|
||||
TrustedDomainNameInformation = 1,
|
||||
|
||||
/// <summary>This value is obsolete.</summary>
|
||||
TrustedControllersInformation,
|
||||
|
@ -369,6 +426,237 @@ namespace Vanara.PInvoke
|
|||
public IntPtr AuthInfo;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <c>POLICY_ACCOUNT_DOMAIN_INFO</c> structure is used to set and query the name and SID of the system's account domain. The
|
||||
/// LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this structure when their InformationClass parameters are set
|
||||
/// to <c>PolicyAccountDomainInformation</c>.
|
||||
/// </summary>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/lsalookup/ns-lsalookup-policy_account_domain_info typedef struct
|
||||
// _POLICY_ACCOUNT_DOMAIN_INFO { LSA_UNICODE_STRING DomainName; PSID DomainSid; } POLICY_ACCOUNT_DOMAIN_INFO, *PPOLICY_ACCOUNT_DOMAIN_INFO;
|
||||
[PInvokeData("lsalookup.h", MSDNShortId = "0e38ac5f-40db-405d-9394-b6bcb7c652b5")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POLICY_ACCOUNT_DOMAIN_INFO
|
||||
{
|
||||
/// <summary>An LSA_UNICODE_STRING structure that specifies the name of the account domain.</summary>
|
||||
public LSA_UNICODE_STRING DomainName;
|
||||
|
||||
/// <summary>Pointer to the SID of the account domain.</summary>
|
||||
public PSID DomainSid;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <c>POLICY_AUDIT_EVENTS_INFO</c> structure is used to set and query the system's auditing rules. The LsaQueryInformationPolicy
|
||||
/// and LsaSetInformationPolicy functions use this structure when their InformationClass parameters are set to <c>PolicyAuditEventsInformation</c>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// LSA Policy defines a mask for the valid event auditing options. The POLICY_AUDIT_EVENT_MASK mask evaluates to <c>TRUE</c> if it
|
||||
/// is set equal to any of the preceding event auditing options.
|
||||
/// </remarks>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-policy_audit_events_info typedef struct
|
||||
// _POLICY_AUDIT_EVENTS_INFO { BOOLEAN AuditingMode; PPOLICY_AUDIT_EVENT_OPTIONS EventAuditingOptions; ULONG MaximumAuditEventCount;
|
||||
// } POLICY_AUDIT_EVENTS_INFO, *PPOLICY_AUDIT_EVENTS_INFO;
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "3442e5e5-78cf-4bda-ba11-0f51ee40df16")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POLICY_AUDIT_EVENTS_INFO
|
||||
{
|
||||
/// <summary>
|
||||
/// <para>Indicates whether auditing is enabled.</para>
|
||||
/// <para>
|
||||
/// If this flag is <c>TRUE</c>, the system generates audit records according to the event auditing options specified in the
|
||||
/// <c>EventAuditingOptions</c> member.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If this flag is <c>FALSE</c>, the system does not generate audit records. However, note that set operations update the event
|
||||
/// auditing options as specified in the <c>EventAuditingOptions</c> member even when <c>AuditingMode</c> is <c>FALSE</c>.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.U1)]
|
||||
public bool AuditingMode;
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// Pointer to an array of POLICY_AUDIT_EVENT_OPTIONS variables. Each element in this array specifies the auditing options for an
|
||||
/// audit event type. The index of each array element corresponds to an audit event type value in the POLICY_AUDIT_EVENT_TYPE
|
||||
/// enumeration type.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Each POLICY_AUDIT_EVENT_OPTIONS variable in the array can specify the following auditing options. You can also combine the
|
||||
/// success and failure options, POLICY_AUDIT_EVENT_SUCCESS and POLICY_AUDIT_EVENT_FAILURE.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// When LSASetInformationPolicy is called to change the audit policy, any new POLICY_AUDIT_EVENT_OPTIONS array elements are
|
||||
/// added to any existing audit options. Adding a new POLICY_AUDIT_EVENT_OPTIONS element combined with the
|
||||
/// POLICY_AUDIT_EVENT_NONE audit option cancels all previous audit options and begins a new set of options.
|
||||
/// </para>
|
||||
/// <list type="table">
|
||||
/// <listheader>
|
||||
/// <term>Value</term>
|
||||
/// <term>Meaning</term>
|
||||
/// </listheader>
|
||||
/// <item>
|
||||
/// <term>POLICY_AUDIT_EVENT_UNCHANGED</term>
|
||||
/// <term>
|
||||
/// For set operations, specify this value to leave the current options unchanged. For read operations, this value means that no
|
||||
/// audit records for this type are generated. This is the default.
|
||||
/// </term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>POLICY_AUDIT_EVENT_SUCCESS</term>
|
||||
/// <term>Generate audit records for successful events of this type.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>POLICY_AUDIT_EVENT_FAILURE</term>
|
||||
/// <term>Generate audit records for failed attempts to cause an event of this type to occur.</term>
|
||||
/// </item>
|
||||
/// <item>
|
||||
/// <term>POLICY_AUDIT_EVENT_NONE</term>
|
||||
/// <term>Do not generate audit records for events of this type.</term>
|
||||
/// </item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
public IntPtr EventAuditingOptions;
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the number of elements in the <c>EventAuditingOptions</c> array. For set operations, if this value is less than the
|
||||
/// number of audit event types supported by the system, the system does not change the auditing options for event types with
|
||||
/// indexes equal to or higher than the value specified in <c>MaximumAuditEventCount</c>.
|
||||
/// </summary>
|
||||
public uint MaximumAuditEventCount;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <c>POLICY_DNS_DOMAIN_INFO</c> structure is used to set and query Domain Name System (DNS) information about the primary
|
||||
/// domain associated with a Policy object. The LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this structure
|
||||
/// when their InformationClass parameters are set to <c>PolicyDnsDomainInformation</c>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// The <c>POLICY_DNS_DOMAIN_INFO</c> structure is an extended version of the POLICY_PRIMARY_DOMAIN_INFO structure. Setting
|
||||
/// <c>POLICY_DNS_DOMAIN_INFO</c> information will overwrite the corresponding values in the <c>POLICY_PRIMARY_DOMAIN_INFO</c> (name
|
||||
/// and SID), and vice versa.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If the computer associated with the Policy object is not a member of a domain, all structure members except <c>Name</c> are
|
||||
/// <c>NULL</c> or zero.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/lsalookup/ns-lsalookup-policy_dns_domain_info typedef struct
|
||||
// _POLICY_DNS_DOMAIN_INFO { LSA_UNICODE_STRING Name; LSA_UNICODE_STRING DnsDomainName; LSA_UNICODE_STRING DnsForestName; GUID
|
||||
// DomainGuid; PSID Sid; } POLICY_DNS_DOMAIN_INFO, *PPOLICY_DNS_DOMAIN_INFO;
|
||||
[PInvokeData("lsalookup.h", MSDNShortId = "5b2879cf-e0dc-4844-bfe8-bf45460285f1")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POLICY_DNS_DOMAIN_INFO
|
||||
{
|
||||
/// <summary>
|
||||
/// An LSA_UNICODE_STRING structure that specifies the name of the primary domain. This is the same as the primary domain name in
|
||||
/// the POLICY_PRIMARY_DOMAIN_INFO structure.
|
||||
/// </summary>
|
||||
public LSA_UNICODE_STRING Name;
|
||||
|
||||
/// <summary>An LSA_UNICODE_STRING structure that specifies the DNS name of the primary domain.</summary>
|
||||
public LSA_UNICODE_STRING DnsDomainName;
|
||||
|
||||
/// <summary>
|
||||
/// An LSA_UNICODE_STRING structure that specifies the DNS forest name of the primary domain. This is the DNS name of the domain
|
||||
/// at the root of the enterprise.
|
||||
/// </summary>
|
||||
public LSA_UNICODE_STRING DnsForestName;
|
||||
|
||||
/// <summary>A GUID structure that contains the GUID of the primary domain.</summary>
|
||||
public Guid DomainGuid;
|
||||
|
||||
/// <summary>
|
||||
/// Pointer to the SID of the primary domain. This is the same as the primary domain SID in the POLICY_PRIMARY_DOMAIN_INFO structure.
|
||||
/// </summary>
|
||||
public PSID Sid;
|
||||
}
|
||||
|
||||
/// <summary>[Undocumented] Used by <see cref="POLICY_DOMAIN_INFORMATION_CLASS.PolicyDomainEfsInformation"/>.</summary>
|
||||
[PInvokeData("ntsecapi.h")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POLICY_DOMAIN_EFS_INFO
|
||||
{
|
||||
/// <summary>Length of the EFS Information blob</summary>
|
||||
public uint InfoLength;
|
||||
|
||||
/// <summary>Efs blob data</summary>
|
||||
public IntPtr EfsBlob;
|
||||
}
|
||||
|
||||
/// <summary>[Undocumented] Used by <see cref="POLICY_DOMAIN_INFORMATION_CLASS.PolicyDomainKerberosTicketInformation"/>.</summary>
|
||||
[PInvokeData("ntsecapi.h")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POLICY_DOMAIN_KERBEROS_TICKET_INFO
|
||||
{
|
||||
/// <summary>allowed ticket options (POLICY_KERBEROS_* flags )</summary>
|
||||
public uint AuthenticationOptions;
|
||||
|
||||
/// <summary>Maximum lifetime for a service ticket</summary>
|
||||
public FILETIME MaxServiceTicketAge;
|
||||
|
||||
/// <summary>Maximum lifetime for the initial ticket</summary>
|
||||
public FILETIME MaxTicketAge;
|
||||
|
||||
/// <summary>Maximum cumulative age a renewable ticket can be with requring authentication</summary>
|
||||
public FILETIME MaxRenewAge;
|
||||
|
||||
/// <summary>Maximum tolerance for synchronization of computer clocks</summary>
|
||||
public FILETIME MaxClockSkew;
|
||||
|
||||
/// <summary>Reserved</summary>
|
||||
public FILETIME Reserved;
|
||||
}
|
||||
|
||||
/// <summary>[Undocumented] Used by <see cref="POLICY_DOMAIN_INFORMATION_CLASS.PolicyDomainQualityOfServiceInformation"/>.</summary>
|
||||
[PInvokeData("ntsecapi.h")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POLICY_DOMAIN_QUALITY_OF_SERVICE_INFO
|
||||
{
|
||||
/// <summary>Determines what specific QOS actions a machine should take</summary>
|
||||
public POLICY_QOS QualityOfService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <c>POLICY_LSA_SERVER_ROLE_INFO</c> structure is used to set and query the role of an LSA server. The
|
||||
/// LsaQueryInformationPolicy and LsaSetInformationPolicy functions use this structure when their InformationClass parameters are set
|
||||
/// to <c>PolicyLsaServerRoleInformation</c>.
|
||||
/// </summary>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-policy_lsa_server_role_info typedef struct
|
||||
// _POLICY_LSA_SERVER_ROLE_INFO { POLICY_LSA_SERVER_ROLE LsaServerRole; } POLICY_LSA_SERVER_ROLE_INFO, *PPOLICY_LSA_SERVER_ROLE_INFO;
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "f66abe33-d8c8-45b8-9b94-d6890d786aaa")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POLICY_LSA_SERVER_ROLE_INFO
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies one of the values from the POLICY_LSA_SERVER_ROLE enumeration type to indicate a primary or backup LSA server.
|
||||
/// </summary>
|
||||
public POLICY_LSA_SERVER_ROLE LsaServerRole;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <c>POLICY_MODIFICATION_INFO</c> structure is used to query information about the creation time and last modification of the
|
||||
/// LSA database. The LsaQueryInformationPolicy function uses this structure when its InformationClass parameter is set to PolicyModificationInformation.
|
||||
/// </summary>
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/ntsecapi/ns-ntsecapi-policy_modification_info typedef struct
|
||||
// _POLICY_MODIFICATION_INFO { LARGE_INTEGER ModifiedId; LARGE_INTEGER DatabaseCreationTime; } POLICY_MODIFICATION_INFO, *PPOLICY_MODIFICATION_INFO;
|
||||
[PInvokeData("ntsecapi.h", MSDNShortId = "ef4d1d1d-9b1b-4d67-80b8-2b548ec31a87")]
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct POLICY_MODIFICATION_INFO
|
||||
{
|
||||
/// <summary>
|
||||
/// A LARGE_INTEGER structure containing a 64-bit unsigned integer that is incremented each time anything in the LSA database is
|
||||
/// modified. This value is modified only on primary domain controllers.
|
||||
/// </summary>
|
||||
public long ModifiedId;
|
||||
|
||||
/// <summary>
|
||||
/// A LARGE_INTEGER structure that indicates the date and time the LSA database was created. This is a UTC-based time that uses
|
||||
/// the FILETIME format. On backup domain controllers, this value is replicated from the primary domain controller. For more
|
||||
/// information about UTC-based time, see System Time.
|
||||
/// </summary>
|
||||
public FILETIME DatabaseCreationTime;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <para>
|
||||
/// The <c>TRUSTED_DOMAIN_AUTH_INFORMATION</c> structure is used to retrieve authentication information for a trusted domain. The
|
||||
|
@ -500,7 +788,7 @@ namespace Vanara.PInvoke
|
|||
/// Pointer to the security identifier (SID) of the trusted domain. For non-Microsoft trusted domains, this member can be <c>NULL</c>.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public IntPtr Sid;
|
||||
public PSID Sid;
|
||||
|
||||
/// <summary>
|
||||
/// <para>A value that indicates the direction of the trust. This member can be one of the following values.</para>
|
||||
|
@ -678,6 +966,5 @@ namespace Vanara.PInvoke
|
|||
/// </summary>
|
||||
public uint Offset;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -11,94 +11,16 @@ namespace Vanara.PInvoke
|
|||
{
|
||||
public static partial class AdvApi32
|
||||
{
|
||||
/// <summary>Provides a <see cref="SafeHandle"/> for <see cref="PSID"/> that is disposed using <see cref="LocalFree"/>.</summary>
|
||||
public class SafeLocalPSID : SafeHANDLE
|
||||
{
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeLocalPSID"/> class and assigns an existing handle.</summary>
|
||||
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
|
||||
/// <param name="ownsHandle">
|
||||
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
|
||||
/// </param>
|
||||
public SafeLocalPSID(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeLocalPSID"/> class.</summary>
|
||||
private SafeLocalPSID() : base() { }
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="SafeLocalPSID"/> to <see cref="LocalPSID"/>.</summary>
|
||||
/// <param name="h">The safe handle instance.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator PSID(SafeLocalPSID h) => h.handle;
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool InternalReleaseHandle() => LocalFree(handle) == HLOCAL.NULL;
|
||||
}
|
||||
|
||||
/// <summary>Provides an array of SID pointers whose memory is disposed after use.</summary>
|
||||
/// <seealso cref="Vanara.PInvoke.SafeHANDLE"/>
|
||||
/// <seealso cref="System.Collections.Generic.IEnumerable{Vanara.PInvoke.PSID}"/>
|
||||
public class SafeLocalPSIDArray : SafeHANDLE, IEnumerable<PSID>
|
||||
{
|
||||
private List<SafeLocalPSID> items;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeLocalPSID"/> class and assigns an existing handle.</summary>
|
||||
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
|
||||
/// <param name="ownsHandle">
|
||||
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
|
||||
/// </param>
|
||||
public SafeLocalPSIDArray(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafeLocalPSID"/> class.</summary>
|
||||
private SafeLocalPSIDArray() : base() { }
|
||||
|
||||
/// <summary>Gets or sets the length of the array. This value must be set in order to interact with the elements.</summary>
|
||||
/// <value>The length.</value>
|
||||
public int Length
|
||||
{
|
||||
get => items?.Count ?? throw new InvalidOperationException("The length must be set before using this function.");
|
||||
set
|
||||
{
|
||||
if (items != null) throw new InvalidOperationException("The length can only be set once.");
|
||||
items = new List<SafeLocalPSID>(handle.ToIEnum<IntPtr>(value).Select(p => new SafeLocalPSID(p)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the <see cref="PSID"/> at the specified index.</summary>
|
||||
/// <value>The <see cref="PSID"/>.</value>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <returns>The PSID at the specified index.</returns>
|
||||
/// <exception cref="InvalidOperationException">The length must be set before using this function.</exception>
|
||||
public PSID this[int index] => items?[index] ?? throw new InvalidOperationException("The length must be set before using this function.");
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through the collection.</summary>
|
||||
/// <returns>A <see cref="IEnumerator{PSID}"/> that can be used to iterate through the collection.</returns>
|
||||
public IEnumerator<PSID> GetEnumerator() => items.ConvertAll(p => (PSID)p).GetEnumerator();
|
||||
|
||||
/// <inheritdoc/>
|
||||
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<SafeLocalPSID>)items).GetEnumerator();
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool InternalReleaseHandle()
|
||||
{
|
||||
if (items != null)
|
||||
foreach (var p in items)
|
||||
p.Dispose();
|
||||
return LocalFree(handle) == HLOCAL.NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Class representation of the native SID structure.</summary>
|
||||
/// <seealso cref="SafeHGlobalHandle"/>
|
||||
public class SafePSID : SafeMemoryHandle<HeapMemoryMethods>, IEquatable<SafePSID>, IEquatable<PSID>, IEquatable<IntPtr>, ICloneable, ISecurityObject
|
||||
public class SafePSID : SafeMemoryHandle<LocalMemoryMethods>, IEquatable<SafePSID>, IEquatable<PSID>, IEquatable<IntPtr>, ICloneable, ISecurityObject
|
||||
{
|
||||
/// <summary>Equivalent to a NULL pointer to a SID.</summary>
|
||||
public static readonly SafePSID Null = new SafePSID(0);
|
||||
|
||||
/// <summary>A SID representing the Everyone Group (S-1-1-0).</summary>
|
||||
public static readonly SafePSID Everyone = CreateWellKnown(WELL_KNOWN_SID_TYPE.WinWorldSid);
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafePSID"/> class.</summary>
|
||||
/// <param name="psid">The existing <see cref="SafePSID"/> instance to duplicate.</param>
|
||||
public SafePSID(PSID psid) : base(GetLengthSid(psid)) => CopySid(Size, handle, psid);
|
||||
public SafePSID(PSID psid) : base(psid.IsNull ? 0 : GetLengthSid(psid)) { if (!psid.IsNull) CopySid(Size, handle, psid); }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafePSID"/> class.</summary>
|
||||
/// <param name="size">The size of memory to allocate, in bytes.</param>
|
||||
|
@ -121,14 +43,20 @@ namespace Vanara.PInvoke
|
|||
/// <see cref="System.Security.Principal.SecurityIdentifier"/> instance.
|
||||
/// </summary>
|
||||
/// <param name="si">The <see cref="System.Security.Principal.SecurityIdentifier"/> instance.</param>
|
||||
public SafePSID(System.Security.Principal.SecurityIdentifier si) : this(GetBytes(si))
|
||||
public SafePSID(System.Security.Principal.SecurityIdentifier si) : this(si is null ? null : GetBytes(si))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafePSID"/> class.</summary>
|
||||
private SafePSID() : base() { }
|
||||
|
||||
/// <summary>Gets the SID for the current user</summary>
|
||||
/// <value>The current user's SID.</value>
|
||||
public static SafePSID Current => new SafePSID(System.Security.Principal.WindowsIdentity.GetCurrent().User);
|
||||
|
||||
/// <summary>A SID representing the Everyone Group (S-1-1-0).</summary>
|
||||
public static SafePSID Everyone => CreateWellKnown(WELL_KNOWN_SID_TYPE.WinWorldSid);
|
||||
|
||||
/// <summary>
|
||||
/// Verifies that the revision number is within a known range, and that the number of subauthorities is less than the maximum.
|
||||
/// </summary>
|
||||
|
@ -138,12 +66,7 @@ namespace Vanara.PInvoke
|
|||
/// <summary>Copies the specified SID from a memory pointer to a <see cref="SafePSID"/> instance.</summary>
|
||||
/// <param name="psid">The SID pointer. This value remains the responsibility of the caller to release.</param>
|
||||
/// <returns>A <see cref="SafePSID"/> instance.</returns>
|
||||
public static SafePSID CreateFromPtr(IntPtr psid)
|
||||
{
|
||||
var newSid = new SafePSID(GetLengthSid(psid));
|
||||
CopySid(newSid.Size, newSid.handle, psid);
|
||||
return newSid;
|
||||
}
|
||||
public static SafePSID CreateFromPtr(IntPtr psid) => new SafePSID(psid);
|
||||
|
||||
/// <summary>Creates a SID for predefined aliases.</summary>
|
||||
/// <param name="WellKnownSidType">Member of the WELL_KNOWN_SID_TYPE enumeration that specifies what the SID will identify.</param>
|
||||
|
@ -256,7 +179,7 @@ namespace Vanara.PInvoke
|
|||
|
||||
/// <summary>Gets the binary form of this SafePSID.</summary>
|
||||
/// <returns>An array of bytes containing the Sid.</returns>
|
||||
public byte[] GetBinaryForm() => base.GetBytes(0, Size);
|
||||
public byte[] GetBinaryForm() => GetBytes(0, Size);
|
||||
|
||||
/// <summary>Returns a hash code for this instance.</summary>
|
||||
/// <returns>A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.</returns>
|
||||
|
@ -264,7 +187,11 @@ namespace Vanara.PInvoke
|
|||
|
||||
/// <summary>Returns a <see cref="string"/> that represents this instance.</summary>
|
||||
/// <returns>A <see cref="string"/> that represents this instance.</returns>
|
||||
public override string ToString() => ConvertSidToStringSid(this);
|
||||
public override string ToString()
|
||||
{
|
||||
try { return ConvertSidToStringSid(this); }
|
||||
catch { return !IsInvalid && !IsClosed ? "Invalid" : "0"; }
|
||||
}
|
||||
|
||||
/// <summary>Creates a new object that is a copy of the current instance.</summary>
|
||||
/// <returns>A new object that is a copy of this instance.</returns>
|
||||
|
@ -277,5 +204,77 @@ namespace Vanara.PInvoke
|
|||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Provides an array of SID pointers whose memory is disposed after use.</summary>
|
||||
/// <seealso cref="Vanara.PInvoke.SafeHANDLE"/>
|
||||
/// <seealso cref="System.Collections.Generic.IReadOnlyList{Vanara.PInvoke.PSID}"/>
|
||||
public class SafePSIDArray : SafeHANDLE, IReadOnlyList<PSID>
|
||||
{
|
||||
private List<SafePSID> items;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafePSIDArray"/> class and assigns an existing handle.</summary>
|
||||
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
|
||||
/// <param name="ownsHandle">
|
||||
/// <see langword="true"/> to reliably release the handle during the finalization phase; otherwise, <see langword="false"/> (not recommended).
|
||||
/// </param>
|
||||
public SafePSIDArray(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafePSIDArray"/> class.</summary>
|
||||
/// <param name="pSIDs">A list of <see cref="SafePSID"/> instances.</param>
|
||||
public SafePSIDArray(IEnumerable<SafePSID> pSIDs) : this(pSIDs.Select(p => (PSID)p))
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafePSIDArray"/> class.</summary>
|
||||
/// <param name="pSIDs">A list of <see cref="SafePSID"/> instances.</param>
|
||||
public SafePSIDArray(IEnumerable<PSID> pSIDs) : base()
|
||||
{
|
||||
items = pSIDs.Select(p => new SafePSID(p)).ToList();
|
||||
SetHandle(items.Cast<IntPtr>().MarshalToPtr(i => LocalAlloc(LMEM.LPTR, i).DangerousGetHandle(), out _));
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="SafePSIDArray"/> class.</summary>
|
||||
private SafePSIDArray() : base() { }
|
||||
|
||||
/// <summary>Gets or sets the length of the array. This value must be set in order to interact with the elements.</summary>
|
||||
/// <value>The length.</value>
|
||||
public int Count
|
||||
{
|
||||
get => items?.Count ?? throw new InvalidOperationException("The length must be set before using this function.");
|
||||
set
|
||||
{
|
||||
if (items != null) throw new InvalidOperationException("The length can only be set once.");
|
||||
items = new List<SafePSID>(handle.ToIEnum<IntPtr>(value).Select(p => new SafePSID(p)));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Gets the <see cref="PSID"/> at the specified index.</summary>
|
||||
/// <value>The <see cref="PSID"/>.</value>
|
||||
/// <param name="index">The index.</param>
|
||||
/// <returns>The PSID at the specified index.</returns>
|
||||
/// <exception cref="InvalidOperationException">The length must be set before using this function.</exception>
|
||||
public PSID this[int index] => items?[index] ?? throw new InvalidOperationException("The length must be set before using this function.");
|
||||
|
||||
/// <summary>Performs an implicit conversion from <see cref="SafePSIDArray"/> to <see cref="PSID[]"/>.</summary>
|
||||
/// <param name="a">The <see cref="SafePSIDArray"/> instance.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator PSID[](SafePSIDArray a) => a.items.ConvertAll(p => (PSID)p).ToArray();
|
||||
|
||||
/// <summary>Returns an enumerator that iterates through the collection.</summary>
|
||||
/// <returns>A <see cref="IEnumerator{PSID}"/> that can be used to iterate through the collection.</returns>
|
||||
public IEnumerator<PSID> GetEnumerator() => items.ConvertAll(p => (PSID)p).GetEnumerator();
|
||||
|
||||
/// <inheritdoc/>
|
||||
IEnumerator IEnumerable.GetEnumerator() => ((IEnumerable<SafePSID>)items).GetEnumerator();
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override bool InternalReleaseHandle()
|
||||
{
|
||||
if (items != null)
|
||||
foreach (var p in items)
|
||||
p.Dispose();
|
||||
return LocalFree(handle) == HLOCAL.NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3857,7 +3857,7 @@ namespace Vanara.PInvoke
|
|||
[DllImport(Lib.Kernel32, SetLastError = true, ExactSpelling = true)]
|
||||
[PInvokeData("securitybaseapi.h", MSDNShortId = "1A911FCC-6D11-4185-B532-20FE6C7C4B0B")]
|
||||
[return: MarshalAs(UnmanagedType.Bool)]
|
||||
public static extern bool DeriveCapabilitySidsFromName([MarshalAs(UnmanagedType.LPWStr)] string CapName, out SafeLocalPSIDArray CapabilityGroupSids, out int CapabilityGroupSidCount, out SafeLocalPSIDArray CapabilitySids, out int CapabilitySidCount);
|
||||
public static extern bool DeriveCapabilitySidsFromName([MarshalAs(UnmanagedType.LPWStr)] string CapName, out SafePSIDArray CapabilityGroupSids, out int CapabilityGroupSidCount, out SafePSIDArray CapabilitySids, out int CapabilitySidCount);
|
||||
|
||||
/// <summary>
|
||||
/// The <c>DestroyPrivateObjectSecurity</c> function deletes a private object's security descriptor. For background information, see
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
using NUnit.Framework;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Vanara.InteropServices;
|
||||
using static Vanara.PInvoke.AdvApi32;
|
||||
|
||||
namespace Vanara.PInvoke.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class LsaTests
|
||||
{
|
||||
public SafeLSA_HANDLE hPol;
|
||||
public SafePSID pSid;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void _Setup()
|
||||
{
|
||||
hPol = LsaOpenPolicy(LsaPolicyRights.POLICY_ALL_ACCESS);
|
||||
pSid = SafePSID.Current;
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void _TearDown()
|
||||
{
|
||||
hPol?.Dispose();
|
||||
pSid?.Dispose();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaAddEnumRemoveAccountRightsTest()
|
||||
{
|
||||
var rights = new[] { "SeBatchLogonRight", "SeRemoteInteractiveLogonRight" };
|
||||
Assert.That(LsaAddAccountRights(hPol, pSid, rights, (uint)rights.Length), ResultIs.Successful);
|
||||
string[] erights = null;
|
||||
Assert.That(() => erights = LsaEnumerateAccountRights(hPol, pSid).ToArray(), Throws.Nothing);
|
||||
Assert.That(erights, Is.EquivalentTo(rights));
|
||||
Assert.That(LsaRemoveAccountRights(hPol, pSid, false, rights, (uint)rights.Length), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaCreateAccountTest()
|
||||
{
|
||||
Assert.That(LsaCreateAccount(hPol, pSid, LsaAccountAccessMask.ACCOUNT_ALL_ACCESS, out var hAcct), ResultIs.Successful);
|
||||
hAcct.Dispose();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaCreateTrustedDomainExTest()
|
||||
{
|
||||
var tdi = new TRUSTED_DOMAIN_INFORMATION_EX
|
||||
{
|
||||
Name = new SafeLSA_UNICODE_STRING("MINE"),
|
||||
Sid = pSid,
|
||||
TrustType = TrustType.TRUST_TYPE_MIT,
|
||||
TrustAttributes = TrustAttributes.TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL,
|
||||
TrustDirection = TrustDirection.TRUST_DIRECTION_DISABLED
|
||||
};
|
||||
var tdai = new TRUSTED_DOMAIN_AUTH_INFORMATION { };
|
||||
Assert.That(LsaCreateTrustedDomainEx(hPol, tdi, tdai, ACCESS_MASK.GENERIC_ALL, out var hDom), ResultIs.Failure);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaDeleteTrustedDomainTest() => Assert.That(LsaDeleteTrustedDomain(hPol, pSid), ResultIs.Failure);
|
||||
|
||||
[Test]
|
||||
public void LsaEnumerateAccountsWithUserRightTest()
|
||||
{
|
||||
PSID[] sids = null;
|
||||
Assert.That(() => sids = LsaEnumerateAccountsWithUserRight(hPol).ToArray(), Throws.Nothing);
|
||||
Assert.That(sids, Is.Not.Empty);
|
||||
TestContext.Write(string.Join("\n", sids.Select(ConvertSidToStringSid)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaEnumerateTrustedDomainsTest()
|
||||
{
|
||||
LSA_TRUST_INFORMATION[] tis = null;
|
||||
Assert.That(() => tis = LsaEnumerateTrustedDomains(hPol).ToArray(), Throws.Nothing);
|
||||
tis.WriteValues();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaGetAppliedCAPIDsTest() => Assert.That(() => LsaGetAppliedCAPIDs().WriteValues(), Throws.Nothing);
|
||||
|
||||
[Test]
|
||||
public void LsaLookupNames2Test()
|
||||
{
|
||||
var names = new[] { Environment.UserDomainName, Environment.UserName };
|
||||
Assert.That(LsaLookupNames2(hPol, LsaLookupNamesFlags.LSA_LOOKUP_ISOLATED_AS_LOCAL, (uint)names.Length, names,
|
||||
out var memDoms, out var memSids), ResultIs.Successful);
|
||||
using (memDoms)
|
||||
using (memSids)
|
||||
{
|
||||
var doms = memDoms.ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.ToArray();
|
||||
var sids = memSids.ToArray<LSA_TRANSLATED_SID2>(names.Length);
|
||||
for (var i = 0; i < names.Length; i++)
|
||||
TestContext.WriteLine((names[i], sids[i].Use, (SafePSID)sids[i].Sid, sids[i].DomainIndex == -1 ? (string)null : doms[sids[i].DomainIndex].Name));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaLookupNamesTest()
|
||||
{
|
||||
var names = new[] { Environment.UserDomainName, Environment.UserName };
|
||||
Assert.That(LsaLookupNames(hPol, (uint)names.Length, names, out var memDoms, out var memSids), ResultIs.Successful);
|
||||
using (memDoms)
|
||||
using (memSids)
|
||||
{
|
||||
var doms = memDoms.ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.ToArray();
|
||||
var sids = memSids.ToArray<LSA_TRANSLATED_SID>(names.Length);
|
||||
for (var i = 0; i < names.Length; i++)
|
||||
TestContext.WriteLine((names[i], sids[i].Use, sids[i].RelativeId, doms[sids[i].DomainIndex].Name));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaLookupPrivilegeValueTest() => Assert.That(LsaLookupPrivilegeValue(hPol, "SeSecurityPrivilege", out var luid), ResultIs.Successful);
|
||||
|
||||
[Test]
|
||||
public void LsaLookupSids2Test()
|
||||
{
|
||||
var sids = new PSID[] { pSid };
|
||||
Assert.That(LsaLookupSids2(hPol, LsaLookupSidsFlags.LSA_LOOKUP_PREFER_INTERNET_NAMES, (uint)sids.Length, sids, out var memDoms, out var memNames), ResultIs.Successful);
|
||||
using (memDoms)
|
||||
using (memNames)
|
||||
{
|
||||
var doms = memDoms.ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.ToArray();
|
||||
var names = memNames.ToArray<LSA_TRANSLATED_NAME>(sids.Length);
|
||||
for (var i = 0; i < sids.Length; i++)
|
||||
TestContext.WriteLine(((SafePSID)sids[i], names[i].Use, names[i].Name, names[i].DomainIndex == -1 ? (string)null : doms[names[i].DomainIndex].Name));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaLookupSidsTest()
|
||||
{
|
||||
var sids = new PSID[] { pSid };
|
||||
Assert.That(LsaLookupSids(hPol, (uint)sids.Length, sids, out var memDoms, out var memNames), ResultIs.Successful);
|
||||
using (memDoms)
|
||||
using (memNames)
|
||||
{
|
||||
var doms = memDoms.ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.ToArray();
|
||||
var names = memNames.ToArray<LSA_TRANSLATED_NAME>(sids.Length);
|
||||
for (var i = 0; i < sids.Length; i++)
|
||||
TestContext.WriteLine(((SafePSID)sids[i], names[i].Use, names[i].Name, names[i].DomainIndex == -1 ? (string)null : doms[names[i].DomainIndex].Name));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaOpenGetSetSystemAccessAccountTest()
|
||||
{
|
||||
Assert.That(LsaOpenAccount(hPol, pSid, LsaAccountAccessMask.ACCOUNT_ALL_ACCESS, out var hAcct), ResultIs.Successful);
|
||||
using (hAcct)
|
||||
{
|
||||
Assert.That(LsaGetSystemAccessAccount(hAcct, out var access), ResultIs.Successful);
|
||||
access.WriteValues();
|
||||
Assert.That(LsaSetSystemAccessAccount(hAcct, access), ResultIs.Successful);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaOpenTrustedDomainByNameTest()
|
||||
{
|
||||
Assert.That(LsaOpenTrustedDomainByName(hPol, Environment.UserDomainName, ACCESS_MASK.GENERIC_READ, out var hTD), ResultIs.FailureCode((NTStatus)NTStatus.STATUS_OBJECT_NAME_NOT_FOUND));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaQueryCAPsTest()
|
||||
{
|
||||
var ppsids = new PSID[] { pSid };
|
||||
Assert.That(LsaQueryCAPs(ppsids, (uint)ppsids.Length, out var ptr, out var cnt), ResultIs.FailureCode((NTStatus)NTStatus.STATUS_INVALID_ID_AUTHORITY));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaQuerySetDomainInformationPolicyTest()
|
||||
{
|
||||
Assert.That(LsaQueryDomainInformationPolicy(hPol, POLICY_DOMAIN_INFORMATION_CLASS.PolicyDomainEfsInformation, out var mem), ResultIs.FailureCode((NTStatus)NTStatus.STATUS_OBJECT_NAME_NOT_FOUND));
|
||||
using (var input = SafeHGlobalHandle.CreateFromStructure(new POLICY_DOMAIN_QUALITY_OF_SERVICE_INFO { QualityOfService = POLICY_QOS.POLICY_QOS_DHCP_SERVER_ALLOWED }))
|
||||
Assert.That(LsaSetDomainInformationPolicy(hPol, POLICY_DOMAIN_INFORMATION_CLASS.PolicyDomainQualityOfServiceInformation, input), ResultIs.FailureCode((NTStatus)NTStatus.RPC_NT_INVALID_TAG));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaQuerySetForestTrustInformationTest()
|
||||
{
|
||||
Assert.That(LsaQueryForestTrustInformation(hPol, Environment.UserDomainName, out var mem), ResultIs.FailureCode((NTStatus)NTStatus.STATUS_INVALID_DOMAIN_STATE));
|
||||
LSA_FOREST_TRUST_INFORMATION fti = default;
|
||||
Assert.That(LsaSetForestTrustInformation(hPol, Environment.UserDomainName, fti, false, out var ci), ResultIs.FailureCode((NTStatus)NTStatus.STATUS_INVALID_DOMAIN_STATE));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaQuerySetInformationPolicyTest()
|
||||
{
|
||||
Assert.That(LsaQueryInformationPolicy(hPol, POLICY_INFORMATION_CLASS.PolicyDnsDomainInformation, out var mem), ResultIs.Successful);
|
||||
mem.ToStructure<POLICY_DNS_DOMAIN_INFO>().WriteValues();
|
||||
Assert.That(LsaSetInformationPolicy(hPol, POLICY_INFORMATION_CLASS.PolicyDnsDomainInformation, mem.DangerousGetHandle()), ResultIs.Successful);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaQuerySetTrustedDomainInfoByNameTest()
|
||||
{
|
||||
Assert.That(LsaQueryTrustedDomainInfoByName(hPol, Environment.UserDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainNameInformation, out var mem), ResultIs.FailureCode((NTStatus)NTStatus.STATUS_OBJECT_NAME_NOT_FOUND));
|
||||
using (var hGl = SafeHGlobalHandle.CreateFromStructure<TRUSTED_DOMAIN_NAME_INFO>())
|
||||
Assert.That(LsaSetTrustedDomainInfoByName(hPol, Environment.UserDomainName, TRUSTED_INFORMATION_CLASS.TrustedDomainNameInformation, hGl), ResultIs.FailureCode((NTStatus)NTStatus.STATUS_INVALID_INFO_CLASS));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaQuerySetTrustedDomainInfoTest()
|
||||
{
|
||||
var dsid = GetDomainSid();
|
||||
Assert.That(LsaQueryTrustedDomainInfo(hPol, dsid, TRUSTED_INFORMATION_CLASS.TrustedDomainNameInformation, out var mem), ResultIs.FailureCode((NTStatus)NTStatus.STATUS_INVALID_HANDLE));
|
||||
using (var hGl = SafeHGlobalHandle.CreateFromStructure<TRUSTED_DOMAIN_NAME_INFO>())
|
||||
Assert.That(LsaSetTrustedDomainInformation(hPol, dsid, TRUSTED_INFORMATION_CLASS.TrustedDomainNameInformation, hGl), ResultIs.Failure);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void LsaStoreRetrievePrivateDataTest()
|
||||
{
|
||||
const string keyName = "Random";
|
||||
Assert.That(LsaStorePrivateData(hPol, keyName, keyName), ResultIs.Successful);
|
||||
Assert.That(LsaRetrievePrivateData(hPol, keyName, out var privData), ResultIs.Successful); //FailureCode((NTStatus)NTStatus.STATUS_OBJECT_NAME_NOT_FOUND));
|
||||
Assert.That(privData.ToStructure<LSA_UNICODE_STRING>().ToString(), Is.EqualTo(keyName));
|
||||
}
|
||||
|
||||
private SafePSID GetDomainSid(string name = null)
|
||||
{
|
||||
var names = new[] { name ?? System.Environment.UserDomainName };
|
||||
Assert.That(LsaLookupNames2(hPol, LsaLookupNamesFlags.LSA_LOOKUP_ISOLATED_AS_LOCAL, (uint)names.Length, names,
|
||||
out var memDoms, out var memSids), ResultIs.Successful);
|
||||
using (memDoms)
|
||||
using (memSids)
|
||||
{
|
||||
var doms = memDoms.ToStructure<LSA_REFERENCED_DOMAIN_LIST>().DomainList.ToArray();
|
||||
return doms.Length == 0 ? SafePSID.Null : new SafePSID(doms[0].Sid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -55,8 +55,8 @@ namespace Vanara.PInvoke.Tests
|
|||
public void DeriveCapabilitySidsFromNameTest()
|
||||
{
|
||||
Assert.That(DeriveCapabilitySidsFromName("microsoft.hsaTestCustomCapability_q536wpkpf5cy2", out var grpsids, out var grpcnt, out var sids, out var cnt), ResultIs.Successful);
|
||||
grpsids.Length = grpcnt; sids.Length = cnt;
|
||||
Assert.That(grpsids.Length, Is.EqualTo(grpcnt));
|
||||
grpsids.Count = grpcnt; sids.Count = cnt;
|
||||
Assert.That(grpsids.Count, Is.EqualTo(grpcnt));
|
||||
Assert.That(grpsids, Is.Not.Empty);
|
||||
Assert.That(sids, Is.Not.Empty);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
<Compile Include="AdvApi32\AuditTests.cs" />
|
||||
<Compile Include="AdvApi32\AppMgmtTests.cs" />
|
||||
<Compile Include="AdvApi32\ProviderInfo.cs" />
|
||||
<Compile Include="AdvApi32\LsaTests.cs" />
|
||||
<Compile Include="AdvApi32\SecurityBaseApiTests.cs" />
|
||||
<Compile Include="AdvApi32\ServiceTests.cs" />
|
||||
<Compile Include="AdvApi32\PSIDTests.cs" />
|
||||
|
|
|
@ -14,31 +14,5 @@ namespace Vanara.PInvoke.Tests
|
|||
[TestFixture()]
|
||||
public class SecurityTests
|
||||
{
|
||||
[Test]
|
||||
public void StructMarshalTest()
|
||||
{
|
||||
bool allGood = true;
|
||||
using (var mem = new SafeHGlobalHandle(4096))
|
||||
{
|
||||
//foreach (var asm in Assembly.GetExecutingAssembly().GetReferencedAssemblies().Where(n => n.Name.StartsWith("Vanara")).Select(n => Assembly.Load(n)))
|
||||
//{
|
||||
var asm = typeof(Vanara.PInvoke.AdvApi32).Assembly;
|
||||
foreach (var tstr in asm.GetTypes().Where(t => t.IsValueType && !t.IsPrimitive && !t.IsEnum && !t.IsGenericType))
|
||||
{
|
||||
if (tstr.Name.StartsWith("<>")) continue;
|
||||
try
|
||||
{
|
||||
Marshal.PtrToStructure(mem.DangerousGetHandle(), tstr);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
TestContext.WriteLine(e);
|
||||
allGood = false;
|
||||
}
|
||||
}
|
||||
//}
|
||||
}
|
||||
Assert.That(allGood);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue