Work on fixing and enabling Audit log writes using AuthzReportSecurityEvent and AuthzReportSecurityEventFromParams. The prior is now fully working. (#251)

pull/256/head
dahall 2021-11-09 13:16:27 -07:00
parent 0cbf6e4041
commit 03bd938b7c
3 changed files with 358 additions and 433 deletions

View File

@ -1,5 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
namespace Vanara.PInvoke
@ -7,8 +10,8 @@ namespace Vanara.PInvoke
public static partial class Authz
{
/// <summary>The <c>AUDIT_PARAM_TYPE</c> enumeration defines the type of audit parameters that are available.</summary>
// https://docs.microsoft.com/en-us/windows/desktop/api/adtgen/ne-adtgen-_audit_param_type typedef enum _AUDIT_PARAM_TYPE { APT_None,
// APT_String, APT_Ulong, APT_Pointer, APT_Sid, APT_LogonId, APT_ObjectTypeList, APT_Luid, APT_Guid, APT_Time, APT_Int64,
// https://docs.microsoft.com/en-us/windows/desktop/api/adtgen/ne-adtgen-_audit_param_type typedef enum _AUDIT_PARAM_TYPE {
// APT_None, APT_String, APT_Ulong, APT_Pointer, APT_Sid, APT_LogonId, APT_ObjectTypeList, APT_Luid, APT_Guid, APT_Time, APT_Int64,
// APT_IpAddress, APT_LogonIdWithSid } AUDIT_PARAM_TYPE;
[PInvokeData("adtgen.h", MSDNShortId = "1ECC866A-2DD3-4EE4-B2CC-7F5ADF7FFC99")]
public enum AUDIT_PARAM_TYPE
@ -17,9 +20,11 @@ namespace Vanara.PInvoke
APT_None = 1,
/// <summary>A string that terminates with NULL.</summary>
[CorrespondingType(typeof(string), EncodingType = typeof(System.Text.UnicodeEncoding))]
APT_String,
/// <summary>An unsigned long.</summary>
[CorrespondingType(typeof(uint))]
APT_Ulong,
/// <summary>
@ -27,39 +32,105 @@ namespace Vanara.PInvoke
/// this option when you are interested in the absolute value of the pointer. The memory to which the pointer points is not
/// marshaled when using this type.
/// </summary>
[CorrespondingType(typeof(IntPtr))]
APT_Pointer,
/// <summary>The security identifier (SID).</summary>
[CorrespondingType(typeof(PSID))]
APT_Sid,
/// <summary>The logon identifier (LUID) that results in three output parameters:</summary>
/// <summary>
/// The logon identifier (LUID) that results in three output parameters:
/// <para>1. Account Name 2. Authority Name 3. LogonID</para>
/// </summary>
[CorrespondingType(typeof(uint))]
APT_LogonId,
/// <summary>Object type list.</summary>
[CorrespondingType(typeof(AUDIT_OBJECT_TYPES))]
APT_ObjectTypeList,
/// <summary>LUID that is not translated to LogonId.</summary>
[CorrespondingType(typeof(uint))]
APT_Luid,
/// <summary>GUID.</summary>
[CorrespondingType(typeof(GuidPtr))]
APT_Guid,
/// <summary>Time as FILETIME.</summary>
[CorrespondingType(typeof(System.Runtime.InteropServices.ComTypes.FILETIME))]
APT_Time,
/// <summary>ULONGLONG.</summary>
/// <summary>LONGLONG.</summary>
[CorrespondingType(typeof(long))]
APT_Int64,
/// <summary>
/// IP Address (IPv4 and IPv6). This logs the address as the first parameter and the port as the second parameter. You must
/// ensure that two entries are added in the event message file. You should ensure that the buffer size is 128 bytes.
/// </summary>
[CorrespondingType(typeof(byte[]))]
APT_IpAddress,
/// <summary>Logon ID with SID that results in four output parameters:</summary>
/// <summary>
/// Logon ID with SID that results in four output parameters:
/// <para>1. SID 2. Account Name 3. Authority Name 4. LogonID</para>
/// </summary>
APT_LogonIdWithSid,
}
/// <summary>
/// IP Addess (IPv4 and IPv6). This logs the address as the first parameter and the port as the second. So ensure that 2 entries are
/// added in the event message file, one for the address and the immediate next entry as the port
/// </summary>
[PInvokeData("adtgen.h")]
[StructLayout(LayoutKind.Sequential)]
public struct AUDIT_IP_ADDRESS
{
private const int _AUTHZ_SS_MAXSIZE = 128;
/// <summary>The IP address bytes.</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = _AUTHZ_SS_MAXSIZE)]
public byte[] pIpAddress;
}
/// <summary>Element of an object-type-list</summary>
[PInvokeData("adtgen.h")]
[StructLayout(LayoutKind.Sequential)]
public struct AUDIT_OBJECT_TYPE
{
/// <summary>guid of the (sub)object</summary>
public Guid ObjectType;
/// <summary>currently not defined</summary>
public ushort Flags;
/// <summary>level within the hierarchy. 0 is the root level</summary>
public ushort Level;
/// <summary>access-mask for this (sub)object</summary>
public ACCESS_MASK AccessMask;
}
/// <summary>
/// The AUDIT_OBJECT_TYPES structure identifies an object type element in a hierarchy of object types. The AccessCheckByType
/// functions use an array of such structures to define a hierarchy of an object and its subobjects, such as property sets and properties.
/// </summary>
[PInvokeData("adtgen.h")]
[StructLayout(LayoutKind.Sequential)]
public struct AUDIT_OBJECT_TYPES
{
/// <summary>number of object-types in pObjectTypes</summary>
public ushort Count;
/// <summary>currently not defined</summary>
public ushort Flags;
/// <summary>array of object-types (i.e. AUDIT_OBJECT_TYPE[])</summary>
public IntPtr pObjectTypes;
}
/// <summary>
/// Structure that defines a single audit parameter. LsaGenAuditEvent accepts an array of such elements to represent the parameters
/// of the audit to be generated. It is best to initialize this structure using AdtInitParams function. This will ensure
@ -69,15 +140,15 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Explicit, Size = 32, CharSet = CharSet.Unicode)]
public struct AUDIT_PARAM
{
/// <summary/>
/// <summary>Type</summary>
[FieldOffset(0)]
public AUDIT_PARAM_TYPE Type;
/// <summary/>
/// <summary>currently unused</summary>
[FieldOffset(4)]
public uint Length;
/// <summary/>
/// <summary>currently unused</summary>
[FieldOffset(8)]
public uint Flags;
@ -99,11 +170,11 @@ namespace Vanara.PInvoke
/// <summary/>
[FieldOffset(16)]
public IntPtr pguid;
public GuidPtr pguid;
/// <summary/>
[FieldOffset(16)]
public int LogonId_LowPart;
public uint LogonId_LowPart;
/// <summary/>
[FieldOffset(16)]
@ -127,17 +198,17 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct AUDIT_PARAMS
{
/// <summary/>
/// <summary>size in bytes</summary>
public uint Length;
/// <summary/>
/// <summary>currently unused</summary>
public uint Flags;
/// <summary/>
/// <summary>number of parameters</summary>
public ushort Count;
/// <summary/>
/// <summary>array of parameters (i.e. AUDIT_PARAM[])</summary>
public IntPtr Parameters;
}
}
}
}

View File

@ -943,17 +943,14 @@ namespace Vanara.PInvoke
/// <returns>An array of AUTHZ_SOURCE_SCHEMA_REGISTRATION structures that returns the registered security event sources.</returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/authz/nf-authz-authzenumeratesecurityeventsources AUTHZAPI BOOL
[PInvokeData("authz.h", MSDNShortId = "2a20ccc9-f2ac-41e4-9d86-745004775e67")]
public static IEnumerable<SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION> AuthzEnumerateSecurityEventSources()
public static IEnumerable<AUTHZ_SOURCE_SCHEMA_REGISTRATION> AuthzEnumerateSecurityEventSources()
{
var len = 0U;
if (!AuthzEnumerateSecurityEventSources(0, IntPtr.Zero, out _, ref len) && len == 0)
Win32Error.ThrowLastError();
using (var mem = new SafeHGlobalHandle((int)len))
{
if (!AuthzEnumerateSecurityEventSources(0, (IntPtr)mem, out var cnt, ref len))
Win32Error.ThrowLastError();
return mem.ToEnumerable<AUTHZ_SOURCE_SCHEMA_REGISTRATION>((int)cnt).Select(r => new SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION(r)).ToArray();
}
using var mem = new SafeHGlobalHandle((int)len);
Win32Error.ThrowLastErrorIfFalse(AuthzEnumerateSecurityEventSources(0, mem, out var cnt, ref len));
return mem.ToEnumerable<AUTHZ_SOURCE_SCHEMA_REGISTRATION>((int)cnt).ToArray();
}
/// <summary>
@ -1679,7 +1676,8 @@ namespace Vanara.PInvoke
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true)]
[PInvokeData("authz.h", MSDNShortId = "77cb5c6c-1634-4449-8d05-ce6357ad4e4b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzInstallSecurityEventSource([Optional] uint dwFlags, in AUTHZ_SOURCE_SCHEMA_REGISTRATION pRegistration);
public static extern bool AuthzInstallSecurityEventSource([Optional] uint dwFlags,
[In, MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(VanaraCustomMarshaler<AUTHZ_SOURCE_SCHEMA_REGISTRATION>))] AUTHZ_SOURCE_SCHEMA_REGISTRATION pRegistration);
/// <summary>
/// <para>The <c>AuthzModifyClaims</c> function adds, deletes, or modifies user and device claims in the Authz client context.</para>
@ -1921,32 +1919,23 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/desktop/api/authz/nf-authz-authzreportsecurityevent AUTHZAPI BOOL
// AuthzReportSecurityEvent( DWORD dwFlags, AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEventProvider, DWORD dwAuditId, PSID pUserSid,
// DWORD dwCount, ... );
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true)]
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
[PInvokeData("authz.h", MSDNShortId = "95d561ef-3233-433a-a1e7-b914df1dd211")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzReportSecurityEvent(APF dwFlags, AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEventProvider, uint dwAuditId, [Optional] PSID pUserSid, uint dwCount, __arglist);
public static extern bool AuthzReportSecurityEvent(APF dwFlags, AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEventProvider, uint dwAuditId,
[Optional] PSID pUserSid, uint dwCount, __arglist);
/// <summary>
/// <para>
/// The <c>AuthzReportSecurityEventFromParams</c> function generates a security audit for a registered security event source by using
/// the specified array of audit parameters.
/// </para>
/// The <c>AuthzReportSecurityEventFromParams</c> function generates a security audit for a registered security event source by
/// using the specified array of audit parameters.
/// </summary>
/// <param name="dwFlags">
/// <para>Reserved for future use.</para>
/// </param>
/// <param name="hEventProvider">
/// <para>A handle to the registered security event source to use for the audit.</para>
/// </param>
/// <param name="dwAuditId">
/// <para>The identifier of the audit.</para>
/// </param>
/// <param name="dwFlags">Reserved for future use.</param>
/// <param name="hEventProvider">A handle to the registered security event source to use for the audit.</param>
/// <param name="dwAuditId">The identifier of the audit.</param>
/// <param name="pUserSid">
/// <para>A pointer to the security identifier (SID) that will be listed as the source of the audit in the event log.</para>
/// </param>
/// <param name="pParams">
/// <para>An array of audit parameters.</para>
/// A pointer to the security identifier (SID) that will be listed as the source of the audit in the event log.
/// </param>
/// <param name="pParams">An array of audit parameters.</param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
@ -1954,10 +1943,35 @@ namespace Vanara.PInvoke
// https://docs.microsoft.com/en-us/windows/desktop/api/authz/nf-authz-authzreportsecurityeventfromparams AUTHZAPI BOOL
// AuthzReportSecurityEventFromParams( DWORD dwFlags, AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEventProvider, DWORD dwAuditId, PSID
// pUserSid, PAUDIT_PARAMS pParams );
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true)]
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("authz.h", MSDNShortId = "ee5b598a-0a89-4b32-a9bc-e9c811573b08")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzReportSecurityEventFromParams([Optional] uint dwFlags, AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEventProvider, uint dwAuditId, [Optional] PSID pUserSid, in AUDIT_PARAMS pParams);
public static extern bool AuthzReportSecurityEventFromParams([Optional] uint dwFlags, AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEventProvider,
uint dwAuditId, [Optional] PSID pUserSid, in AUDIT_PARAMS pParams);
/// <summary>
/// The <c>AuthzReportSecurityEventFromParams</c> function generates a security audit for a registered security event source by
/// using the specified array of audit parameters.
/// </summary>
/// <param name="dwFlags">Reserved for future use.</param>
/// <param name="hEventProvider">A handle to the registered security event source to use for the audit.</param>
/// <param name="dwAuditId">The identifier of the audit.</param>
/// <param name="pUserSid">
/// A pointer to the security identifier (SID) that will be listed as the source of the audit in the event log.
/// </param>
/// <param name="pParams">An array of audit parameters.</param>
/// <returns>
/// <para>If the function succeeds, the function returns <c>TRUE</c>.</para>
/// <para>If the function fails, it returns <c>FALSE</c>. For extended error information, call GetLastError.</para>
/// </returns>
// https://docs.microsoft.com/en-us/windows/desktop/api/authz/nf-authz-authzreportsecurityeventfromparams AUTHZAPI BOOL
// AuthzReportSecurityEventFromParams( DWORD dwFlags, AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEventProvider, DWORD dwAuditId, PSID
// pUserSid, PAUDIT_PARAMS pParams );
[DllImport(Lib.Authz, SetLastError = true, ExactSpelling = true, CharSet = CharSet.Unicode)]
[PInvokeData("authz.h", MSDNShortId = "ee5b598a-0a89-4b32-a9bc-e9c811573b08")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool AuthzReportSecurityEventFromParams([Optional] uint dwFlags, AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEventProvider,
uint dwAuditId, [Optional] PSID pUserSid, [In, MarshalAs(UnmanagedType.LPArray)] AUDIT_PARAMS[] pParams);
/// <summary>
/// The <c>AuthzSetAppContainerInformation</c> function sets the app container and capability information in a current Authz context.
@ -2052,14 +2066,14 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_ACCESS_CHECK_RESULTS_HANDLE : IHandle
{
private IntPtr handle;
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static AUTHZ_ACCESS_CHECK_RESULTS_HANDLE NULL => new AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(IntPtr.Zero);
public static AUTHZ_ACCESS_CHECK_RESULTS_HANDLE NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
@ -2072,7 +2086,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_ACCESS_CHECK_RESULTS_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(IntPtr h) => new AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(h);
public static implicit operator AUTHZ_ACCESS_CHECK_RESULTS_HANDLE(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
@ -2087,7 +2101,7 @@ namespace Vanara.PInvoke
public static bool operator ==(AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h1, AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h ? handle == h.handle : false;
public override bool Equals(object obj) => obj is AUTHZ_ACCESS_CHECK_RESULTS_HANDLE h && handle == h.handle;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
@ -2140,14 +2154,14 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_AUDIT_EVENT_HANDLE : IHandle
{
private IntPtr handle;
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public AUTHZ_AUDIT_EVENT_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static AUTHZ_AUDIT_EVENT_HANDLE NULL => new AUTHZ_AUDIT_EVENT_HANDLE(IntPtr.Zero);
public static AUTHZ_AUDIT_EVENT_HANDLE NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
@ -2160,7 +2174,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_AUDIT_EVENT_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_AUDIT_EVENT_HANDLE(IntPtr h) => new AUTHZ_AUDIT_EVENT_HANDLE(h);
public static implicit operator AUTHZ_AUDIT_EVENT_HANDLE(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
@ -2175,7 +2189,7 @@ namespace Vanara.PInvoke
public static bool operator ==(AUTHZ_AUDIT_EVENT_HANDLE h1, AUTHZ_AUDIT_EVENT_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_AUDIT_EVENT_HANDLE h ? handle == h.handle : false;
public override bool Equals(object obj) => obj is AUTHZ_AUDIT_EVENT_HANDLE h && handle == h.handle;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
@ -2188,7 +2202,7 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE : IHandle
{
private IntPtr handle;
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
@ -2197,7 +2211,7 @@ namespace Vanara.PInvoke
/// <summary>
/// Returns an invalid handle by instantiating a <see cref="AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE"/> object with <see cref="IntPtr.Zero"/>.
/// </summary>
public static AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE NULL => new AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE(IntPtr.Zero);
public static AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
@ -2210,7 +2224,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE(IntPtr h) => new AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE(h);
public static implicit operator AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
@ -2225,7 +2239,7 @@ namespace Vanara.PInvoke
public static bool operator ==(AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE h1, AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE h ? handle == h.handle : false;
public override bool Equals(object obj) => obj is AUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE h && handle == h.handle;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
@ -2238,14 +2252,14 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_CLIENT_CONTEXT_HANDLE : IHandle
{
private IntPtr handle;
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_CLIENT_CONTEXT_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public AUTHZ_CLIENT_CONTEXT_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="AUTHZ_CLIENT_CONTEXT_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static AUTHZ_CLIENT_CONTEXT_HANDLE NULL => new AUTHZ_CLIENT_CONTEXT_HANDLE(IntPtr.Zero);
public static AUTHZ_CLIENT_CONTEXT_HANDLE NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
@ -2258,7 +2272,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_CLIENT_CONTEXT_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_CLIENT_CONTEXT_HANDLE(IntPtr h) => new AUTHZ_CLIENT_CONTEXT_HANDLE(h);
public static implicit operator AUTHZ_CLIENT_CONTEXT_HANDLE(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
@ -2273,7 +2287,7 @@ namespace Vanara.PInvoke
public static bool operator ==(AUTHZ_CLIENT_CONTEXT_HANDLE h1, AUTHZ_CLIENT_CONTEXT_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_CLIENT_CONTEXT_HANDLE h ? handle == h.handle : false;
public override bool Equals(object obj) => obj is AUTHZ_CLIENT_CONTEXT_HANDLE h && handle == h.handle;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
@ -2354,11 +2368,12 @@ namespace Vanara.PInvoke
// _AUTHZ_REGISTRATION_OBJECT_TYPE_NAME_OFFSET { PWSTR szObjectTypeName; DWORD dwOffset; }
// AUTHZ_REGISTRATION_OBJECT_TYPE_NAME_OFFSET, *PAUTHZ_REGISTRATION_OBJECT_TYPE_NAME_OFFSET;
[PInvokeData("authz.h", MSDNShortId = "2ec39edc-7819-41a5-8798-dc51c00ba85e")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct AUTHZ_REGISTRATION_OBJECT_TYPE_NAME_OFFSET
{
/// <summary>A pointer to a wide character string that represents the name of the object type.</summary>
public StrPtrUni szObjectTypeName;
[MarshalAs(UnmanagedType.LPTStr)]
public string szObjectTypeName;
/// <summary>Offset of the object type name in an object types message DLL.</summary>
public uint dwOffset;
@ -2368,14 +2383,14 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_RESOURCE_MANAGER_HANDLE : IHandle
{
private IntPtr handle;
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_RESOURCE_MANAGER_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
public AUTHZ_RESOURCE_MANAGER_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// <summary>Returns an invalid handle by instantiating a <see cref="AUTHZ_RESOURCE_MANAGER_HANDLE"/> object with <see cref="IntPtr.Zero"/>.</summary>
public static AUTHZ_RESOURCE_MANAGER_HANDLE NULL => new AUTHZ_RESOURCE_MANAGER_HANDLE(IntPtr.Zero);
public static AUTHZ_RESOURCE_MANAGER_HANDLE NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
@ -2388,7 +2403,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_RESOURCE_MANAGER_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_RESOURCE_MANAGER_HANDLE(IntPtr h) => new AUTHZ_RESOURCE_MANAGER_HANDLE(h);
public static implicit operator AUTHZ_RESOURCE_MANAGER_HANDLE(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
@ -2403,7 +2418,7 @@ namespace Vanara.PInvoke
public static bool operator ==(AUTHZ_RESOURCE_MANAGER_HANDLE h1, AUTHZ_RESOURCE_MANAGER_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_RESOURCE_MANAGER_HANDLE h ? handle == h.handle : false;
public override bool Equals(object obj) => obj is AUTHZ_RESOURCE_MANAGER_HANDLE h && handle == h.handle;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
@ -2608,7 +2623,7 @@ namespace Vanara.PInvoke
[StructLayout(LayoutKind.Sequential)]
public struct AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE : IHandle
{
private IntPtr handle;
private readonly IntPtr handle;
/// <summary>Initializes a new instance of the <see cref="AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE"/> struct.</summary>
/// <param name="preexistingHandle">An <see cref="IntPtr"/> object that represents the pre-existing handle to use.</param>
@ -2617,7 +2632,7 @@ namespace Vanara.PInvoke
/// <summary>
/// Returns an invalid handle by instantiating a <see cref="AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE"/> object with <see cref="IntPtr.Zero"/>.
/// </summary>
public static AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE NULL => new AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE(IntPtr.Zero);
public static AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE NULL => new(IntPtr.Zero);
/// <summary>Gets a value indicating whether this instance is a null handle.</summary>
public bool IsNull => handle == IntPtr.Zero;
@ -2630,7 +2645,7 @@ namespace Vanara.PInvoke
/// <summary>Performs an implicit conversion from <see cref="IntPtr"/> to <see cref="AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE"/>.</summary>
/// <param name="h">The pointer to a handle.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE(IntPtr h) => new AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE(h);
public static implicit operator AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE(IntPtr h) => new(h);
/// <summary>Implements the operator !=.</summary>
/// <param name="h1">The first handle.</param>
@ -2645,7 +2660,7 @@ namespace Vanara.PInvoke
public static bool operator ==(AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE h1, AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object obj) => obj is AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE h ? handle == h.handle : false;
public override bool Equals(object obj) => obj is AUTHZ_SECURITY_EVENT_PROVIDER_HANDLE h && handle == h.handle;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
@ -2662,7 +2677,8 @@ namespace Vanara.PInvoke
// ObjectTypeNames[ANYSIZE_ARRAY]; } AUTHZ_SOURCE_SCHEMA_REGISTRATION, *PAUTHZ_SOURCE_SCHEMA_REGISTRATION;
[PInvokeData("authz.h", MSDNShortId = "8b4d6e14-fb9c-428a-bd94-34eba668edc6")]
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct AUTHZ_SOURCE_SCHEMA_REGISTRATION
[VanaraMarshaler(typeof(SafeAnysizeStructMarshaler<AUTHZ_SOURCE_SCHEMA_REGISTRATION>), nameof(dwObjectTypeNameCount))]
public class AUTHZ_SOURCE_SCHEMA_REGISTRATION
{
/// <summary>
/// <para>Flags that control the behavior of the operation. The following table shows a possible value.</para>
@ -2690,21 +2706,26 @@ namespace Vanara.PInvoke
public SOURCE_SCHEMA_REGISTRATION_FLAGS dwFlags;
/// <summary>A pointer to a wide character string that represents the name of the event source.</summary>
public StrPtrUni szEventSourceName;
[MarshalAs(UnmanagedType.LPTStr)]
public string szEventSourceName;
/// <summary>A pointer to a wide character string that represents the name of the resource that contains the event messages.</summary>
public StrPtrUni szEventMessageFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string szEventMessageFile;
/// <summary>A pointer to a wide character string that represents the name of the XML schema file for the event source.</summary>
public StrPtrUni szEventSourceXmlSchemaFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string szEventSourceXmlSchemaFile;
/// <summary>
/// A pointer to a wide character string that represents the name of the resource that contains the event parameter strings.
/// </summary>
public StrPtrUni szEventAccessStringsFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string szEventAccessStringsFile;
/// <summary>This member is reserved and must be set to <c>NULL</c>.</summary>
public StrPtrUni szExecutableImagePath;
[MarshalAs(UnmanagedType.LPTStr)]
public string szExecutableImagePath;
/// <summary>
/// The GUID of a migrated publisher. The value of this member is converted to a string and stored in the registry if the caller
@ -2716,123 +2737,8 @@ namespace Vanara.PInvoke
public uint dwObjectTypeNameCount;
/// <summary>An array of AUTHZ_REGISTRATION_OBJECT_TYPE_NAME_OFFSET structures that represents the object types for the events.</summary>
public AUTHZ_REGISTRATION_OBJECT_TYPE_NAME_OFFSET ObjectTypeNames;
}
/// <summary/>
public class SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION : IDisposable
{
private List<SafeHGlobalHandle> mem = new List<SafeHGlobalHandle>(7);
/// <summary>
/// <para>Flags that control the behavior of the operation. The following table shows a possible value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>AUTHZ_ALLOW_MULTIPLE_SOURCE_INSTANCES 0x1</term>
/// <term>
/// Allows registration of multiple sources with the same name. Use of this flag means that more than one source can call the
/// AuthzRegisterSecurityEventSource function with the same szEventSourceName at runtime.
/// </term>
/// </item>
/// <item>
/// <term>AUTHZ_MIGRATED_LEGACY_PUBLISHER 0x2</term>
/// <term>
/// The caller is a migrated publisher that has registered a manifest with WEvtUtil.exe. The GUID of the provider specified by
/// the pProviderGuid member is stored in the registry.
/// </term>
/// </item>
/// </list>
/// </summary>
public SOURCE_SCHEMA_REGISTRATION_FLAGS dwFlags { get; set; }
/// <summary>A string that represents the name of the event source.</summary>
public string szEventSourceName { get; set; }
/// <summary>A string that represents the name of the resource that contains the event messages.</summary>
public string szEventMessageFile { get; set; }
/// <summary>A string that represents the name of the XML schema file for the event source.</summary>
public string szEventSourceXmlSchemaFile { get; set; }
/// <summary>
/// A pointer to a wide character string that represents the name of the resource that contains the event parameter strings.
/// </summary>
public string szEventAccessStringsFile { get; set; }
/// <summary>This member is reserved and must be set to <see langword="null"/>.</summary>
public string szExecutableImagePath { get; set; }
/// <summary>
/// The GUID of a migrated publisher. The value of this member is converted to a string and stored in the registry if the caller
/// is a migrated publisher.
/// </summary>
public Guid? pProviderGuid { get; set; }
/// <summary>A pointer to a wide character string that represents the name of the object type.</summary>
public string szObjectTypeName { get; set; }
/// <summary>Offset of the object type name in an object types message DLL.</summary>
public uint dwOffset { get; set; }
/// <summary>Initializes a new instance of the <see cref="SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION"/> class.</summary>
public SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION() { }
/// <summary>
/// Initializes a new instance of the <see cref="SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION"/> class from its unmanaged equivalent.
/// </summary>
/// <param name="outValue">The native <see cref="AUTHZ_SOURCE_SCHEMA_REGISTRATION"/> instance.</param>
public SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION(AUTHZ_SOURCE_SCHEMA_REGISTRATION outValue)
{
dwFlags = outValue.dwFlags;
szEventSourceName = outValue.szEventSourceName;
szEventMessageFile = outValue.szEventMessageFile;
szEventSourceXmlSchemaFile = outValue.szEventSourceXmlSchemaFile;
szEventAccessStringsFile = outValue.szEventAccessStringsFile;
szExecutableImagePath = outValue.szExecutableImagePath;
pProviderGuid = outValue.pProviderGuid;
szObjectTypeName = outValue.ObjectTypeNames.szObjectTypeName;
dwOffset = outValue.ObjectTypeNames.dwOffset;
}
/// <summary>Performs an implicit conversion from <see cref="SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION"/> to <see cref="AUTHZ_SOURCE_SCHEMA_REGISTRATION"/>.</summary>
/// <param name="mgd">The managed equivalent.</param>
/// <returns>The result of the conversion.</returns>
public static implicit operator AUTHZ_SOURCE_SCHEMA_REGISTRATION(SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION mgd)
{
// Write all pointer instances to memory stream so they will be kept in memory
var ret = new AUTHZ_SOURCE_SCHEMA_REGISTRATION { dwFlags = mgd.dwFlags };
ret.szEventSourceName = SetPtr(mgd.szEventSourceName);
ret.szEventMessageFile = SetPtr(mgd.szEventMessageFile);
ret.szEventSourceXmlSchemaFile = SetPtr(mgd.szEventSourceXmlSchemaFile);
ret.szEventAccessStringsFile = SetPtr(mgd.szEventAccessStringsFile);
ret.szExecutableImagePath = SetPtr(mgd.szExecutableImagePath);
if (mgd.pProviderGuid.HasValue)
{
var ptr = SafeHGlobalHandle.CreateFromStructure(mgd.pProviderGuid.Value);
mgd.mem.Add(ptr);
ret.pProviderGuid = ptr.DangerousGetHandle();
}
ret.dwObjectTypeNameCount = mgd.szObjectTypeName is null ? 0 : 1U;
ret.ObjectTypeNames.szObjectTypeName = SetPtr(mgd.szObjectTypeName);
ret.ObjectTypeNames.dwOffset = mgd.dwOffset;
return ret;
IntPtr SetPtr(string value)
{
if (value is null) return IntPtr.Zero;
var ptr = new SafeHGlobalHandle(value);
mgd.mem.Add(ptr);
return ptr.DangerousGetHandle();
}
}
/// <inheritdoc/>
public void Dispose() { foreach (var m in mem) m.Dispose(); mem.Clear(); }
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)]
public AUTHZ_REGISTRATION_OBJECT_TYPE_NAME_OFFSET[] ObjectTypeNames;
}
/// <summary>
@ -2877,23 +2783,17 @@ namespace Vanara.PInvoke
Error = Marshal.AllocHGlobal(sz);
}
#pragma warning disable 612
/// <summary>Gets or sets the granted access mask values. The length of this array must match the value in <see cref="ResultListLength"/>.</summary>
/// <value>The granted access mask values.</value>
public uint[] GrantedAccessMaskValues
{
get
{
if (GrantedAccessMask != IntPtr.Zero && ResultListLength > 0)
return GrantedAccessMask.ToArray<uint>(ResultListLength);
return new uint[0];
}
get => GrantedAccessMask != IntPtr.Zero && ResultListLength > 0 ? GrantedAccessMask.ToArray<uint>(ResultListLength) : (new uint[0]);
set
{
if (value == null && ResultListLength != 0)
if (value is null && ResultListLength != 0)
throw new ArgumentNullException(nameof(GrantedAccessMaskValues), $"Value cannot be null if {nameof(ResultListLength)} field does not equal 0.");
if (value != null && value.Length != ResultListLength)
if (value is not null && value.Length != ResultListLength)
throw new ArgumentOutOfRangeException(nameof(GrantedAccessMaskValues), $"Number of items must match value of {nameof(ResultListLength)} field.");
CopyArrayToPtr(value, GrantedAccessMask);
}
@ -2915,17 +2815,14 @@ namespace Vanara.PInvoke
/// <value>The system access control list (SACL) evaluation results values.</value>
public uint[] SaclEvaluationResultsValues
{
get
{
if (SaclEvaluationResults != IntPtr.Zero && ResultListLength > 0)
return SaclEvaluationResults.ToArray<uint>(ResultListLength);
return new uint[0];
}
get => SaclEvaluationResults != IntPtr.Zero && ResultListLength > 0
? SaclEvaluationResults.ToArray<uint>(ResultListLength)
: (new uint[0]);
set
{
if (value == null && ResultListLength != 0)
if (value is null && ResultListLength != 0)
throw new ArgumentNullException(nameof(SaclEvaluationResultsValues), $"Value cannot be null if {nameof(ResultListLength)} field does not equal 0.");
if (value != null && value.Length != ResultListLength)
if (value is not null && value.Length != ResultListLength)
throw new ArgumentOutOfRangeException(nameof(SaclEvaluationResultsValues), $"Number of items must match value of {nameof(ResultListLength)} field.");
CopyArrayToPtr(value, SaclEvaluationResults);
}
@ -2935,24 +2832,17 @@ namespace Vanara.PInvoke
/// <value>The results values.</value>
public uint[] ErrorValues
{
get
{
if (Error != IntPtr.Zero && ResultListLength > 0)
return Error.ToArray<uint>(ResultListLength);
return new uint[0];
}
get => Error != IntPtr.Zero && ResultListLength > 0 ? Error.ToArray<uint>(ResultListLength) : (new uint[0]);
set
{
if (value == null && ResultListLength != 0)
if (value is null && ResultListLength != 0)
throw new ArgumentNullException(nameof(ErrorValues), $"Value cannot be null if {nameof(ResultListLength)} field does not equal 0.");
if (value != null && value.Length != ResultListLength)
if (value is not null && value.Length != ResultListLength)
throw new ArgumentOutOfRangeException(nameof(ErrorValues), $"Number of items must match value of {nameof(ResultListLength)} field.");
CopyArrayToPtr(value, Error);
}
}
#pragma warning restore 612
void IDisposable.Dispose()
{
Marshal.FreeHGlobal(GrantedAccessMask);
@ -3152,7 +3042,7 @@ namespace Vanara.PInvoke
internal class AUTHZ_SECURITY_ATTRIBUTES_INFORMATION_Marshaler : ICustomMarshaler
{
public static ICustomMarshaler GetInstance(string cookie) => new AUTHZ_SECURITY_ATTRIBUTES_INFORMATION_Marshaler();
public static ICustomMarshaler GetInstance(string _) => new AUTHZ_SECURITY_ATTRIBUTES_INFORMATION_Marshaler();
public void CleanUpManagedData(object ManagedObj)
{
@ -3165,7 +3055,7 @@ namespace Vanara.PInvoke
public IntPtr MarshalManagedToNative(object ManagedObj)
{
// Determine size
if (!(ManagedObj is AUTHZ_SECURITY_ATTRIBUTES_INFORMATION attrInfo)) throw new InvalidOperationException("This marshaler only works on AUTHZ_SECURITY_ATTRIBUTES_INFORMATION structures.");
if (ManagedObj is not AUTHZ_SECURITY_ATTRIBUTES_INFORMATION attrInfo) throw new InvalidOperationException("This marshaler only works on AUTHZ_SECURITY_ATTRIBUTES_INFORMATION structures.");
var sz1 = Marshal.SizeOf(typeof(Internal_AUTHZ_SECURITY_ATTRIBUTES_INFORMATION)) +
attrInfo.AttributeCount * Marshal.SizeOf(typeof(Internal_AUTHZ_SECURITY_ATTRIBUTE_V1));
var sz2 = 0L;
@ -3267,7 +3157,7 @@ namespace Vanara.PInvoke
return new AUTHZ_SECURITY_ATTRIBUTES_INFORMATION(attrInfo.pAttributeV1 == IntPtr.Zero ? null :
Array.ConvertAll(attrInfo.pAttributeV1.ToArray<Internal_AUTHZ_SECURITY_ATTRIBUTE_V1>((int)attrInfo.AttributeCount), Conv));
AUTHZ_SECURITY_ATTRIBUTE_V1 Conv(Internal_AUTHZ_SECURITY_ATTRIBUTE_V1 input)
static AUTHZ_SECURITY_ATTRIBUTE_V1 Conv(Internal_AUTHZ_SECURITY_ATTRIBUTE_V1 input)
{
var v1 = new AUTHZ_SECURITY_ATTRIBUTE_V1 { pName = StringHelper.GetString(input.pName, CharSet.Unicode), Flags = input.Flags, ValueCount = input.ValueCount, ValueType = input.ValueType };
switch (v1.ValueType)

View File

@ -1,8 +1,6 @@
using NUnit.Framework;
using System;
using System.Linq;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
using static Vanara.PInvoke.AdvApi32;
using static Vanara.PInvoke.Authz;
@ -15,198 +13,165 @@ namespace Vanara.PInvoke.Tests
{
public static SafeAUTHZ_AUDIT_EVENT_HANDLE GetAuthzInitializeObjectAccessAuditEvent()
{
var b = AuthzInitializeObjectAccessAuditEvent(AuthzAuditEventFlags.AUTHZ_NO_ALLOC_STRINGS, IntPtr.Zero, "", "", "", "", out var hEvt);
if (!b) TestContext.WriteLine($"AuthzInitializeObjectAccessAuditEvent:{Win32Error.GetLastError()}");
Assert.That(b);
Assert.That(AuthzInitializeObjectAccessAuditEvent(AuthzAuditEventFlags.AUTHZ_NO_ALLOC_STRINGS, IntPtr.Zero, "", "", "", "", out SafeAUTHZ_AUDIT_EVENT_HANDLE hEvt), ResultIs.Successful);
Assert.That(!hEvt.IsInvalid);
return hEvt;
}
public static SafeAUTHZ_RESOURCE_MANAGER_HANDLE GetAuthzInitializeResourceManager()
{
var b = AuthzInitializeResourceManager(AuthzResourceManagerFlags.AUTHZ_RM_FLAG_NO_AUDIT, null, null, null, "Test", out var hResMgr);
if (!b) TestContext.WriteLine($"AuthzInitializeResourceManager:{Win32Error.GetLastError()}");
Assert.That(b);
Assert.That(AuthzInitializeResourceManager(AuthzResourceManagerFlags.AUTHZ_RM_FLAG_NO_AUDIT, null, null, null, "Test", out SafeAUTHZ_RESOURCE_MANAGER_HANDLE hResMgr), ResultIs.Successful);
Assert.That(!hResMgr.IsInvalid);
return hResMgr;
}
public static SafeHGlobalHandle GetCtxInfo(SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS type)
{
var b = AuthzGetInformationFromContext(hCtx, type, 0, out var szReq, IntPtr.Zero);
if (!b && Win32Error.GetLastError() != Win32Error.ERROR_INSUFFICIENT_BUFFER) TestContext.WriteLine($"AuthzGetInformationFromContext:{Win32Error.GetLastError()}");
bool b = AuthzGetInformationFromContext(hCtx, type, 0, out uint szReq, IntPtr.Zero);
if (!b && Win32Error.GetLastError() != Win32Error.ERROR_INSUFFICIENT_BUFFER)
{
TestContext.WriteLine($"AuthzGetInformationFromContext:{Win32Error.GetLastError()}");
}
Assert.That(!b);
if (szReq == 0) return SafeHGlobalHandle.Null;
var buf = new SafeHGlobalHandle((int)szReq);
b = AuthzGetInformationFromContext(hCtx, type, szReq, out szReq, (IntPtr)buf);
if (!b) TestContext.WriteLine($"AuthzGetInformationFromContext:{Win32Error.GetLastError()}");
Assert.That(b);
if (szReq == 0)
{
return SafeHGlobalHandle.Null;
}
SafeHGlobalHandle buf = new((int)szReq);
Assert.That(AuthzGetInformationFromContext(hCtx, type, szReq, out _, buf), ResultIs.Successful);
return buf;
}
public static SafeAUTHZ_CLIENT_CONTEXT_HANDLE GetCurrentUserAuthContext(SafeAUTHZ_RESOURCE_MANAGER_HANDLE hResMgr)
{
var b = AuthzInitializeContextFromSid(AuthzContextFlags.DEFAULT, SafePSID.Current, hResMgr, IntPtr.Zero, new LUID(), IntPtr.Zero, out var hCtx);
if (!b) TestContext.WriteLine($"AuthzInitializeContextFromSid:{Win32Error.GetLastError()}");
Assert.That(b);
Assert.That(AuthzInitializeContextFromSid(AuthzContextFlags.DEFAULT, SafePSID.Current, hResMgr, IntPtr.Zero, new LUID(), IntPtr.Zero, out SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx), ResultIs.Successful);
Assert.That(!hCtx.IsInvalid);
return hCtx;
}
public static SafeAUTHZ_CLIENT_CONTEXT_HANDLE GetTokenAuthContext(SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM)
{
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_QUERY))
{
var b = AuthzInitializeContextFromToken(0, hTok, hRM, IntPtr.Zero, new LUID(), IntPtr.Zero, out var hCtx);
if (!b) TestContext.WriteLine($"AuthzAccessCheck:{Win32Error.GetLastError()}");
Assert.That(b);
Assert.That(!hCtx.IsInvalid);
return hCtx;
}
using SafeHTOKEN hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_QUERY);
Assert.That(AuthzInitializeContextFromToken(0, hTok, hRM, IntPtr.Zero, new LUID(), IntPtr.Zero, out SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx), ResultIs.Successful);
Assert.That(!hCtx.IsInvalid);
return hCtx;
}
[Test]
public void AuthzAddSidsToContextTest()
{
using (var everyoneSid = ConvertStringSidToSid("S-1-1-0"))
using (var localSid = ConvertStringSidToSid("S-1-2-0"))
{
var sids = new SID_AND_ATTRIBUTES { Sid = everyoneSid, Attributes = (uint)GroupAttributes.SE_GROUP_ENABLED };
var restrictedSids = new SID_AND_ATTRIBUTES { Sid = localSid, Attributes = (uint)GroupAttributes.SE_GROUP_ENABLED };
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
Assert.That(AuthzAddSidsToContext(hCtx, sids, 1, restrictedSids, 1, out var hNewCtx), Is.True);
}
using SafePSID everyoneSid = ConvertStringSidToSid("S-1-1-0");
using SafePSID localSid = ConvertStringSidToSid("S-1-2-0");
SID_AND_ATTRIBUTES sids = new() { Sid = everyoneSid, Attributes = (uint)GroupAttributes.SE_GROUP_ENABLED };
SID_AND_ATTRIBUTES restrictedSids = new() { Sid = localSid, Attributes = (uint)GroupAttributes.SE_GROUP_ENABLED };
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
Assert.That(AuthzAddSidsToContext(hCtx, sids, 1, restrictedSids, 1, out SafeAUTHZ_CLIENT_CONTEXT_HANDLE hNewCtx), ResultIs.Successful);
}
[Test]
public void AuthzEnumerateSecurityEventSourcesTest()
{
using (var mem = new SafeNativeArray<AUTHZ_SOURCE_SCHEMA_REGISTRATION>(200))
{
var sz = (uint)mem.Size;
var b = AuthzEnumerateSecurityEventSources(0, (IntPtr)mem, out var len, ref sz);
Assert.That(b, Is.True);
Assert.That(sz, Is.LessThanOrEqualTo(mem.Size));
Assert.That(len, Is.GreaterThan(0));
Assert.That(() => TestContext.WriteLine(string.Join("\n", mem.Take((int)len).Select(r => r.szEventSourceName.ToString()))), Throws.Nothing);
}
}
[Test]
public void AuthzEnumerateSecurityEventSourcesTest2()
{
Assert.That(AuthzEnumerateSecurityEventSources(), Is.Not.Empty);
var srcs = AuthzEnumerateSecurityEventSources().ToArray();
Assert.That(srcs, Is.Not.Empty);
Assert.That(() => TestContext.WriteLine(string.Join("\n", srcs.Select(r => r.szEventSourceName))), Throws.Nothing);
}
[Test]
public void AuthzAccessCheckAndCachedTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
using (var hEvt = GetAuthzInitializeObjectAccessAuditEvent())
using (var psd = AdvApi32Tests.GetSD(TestCaseSources.SmallFile))
using (var reply = new AUTHZ_ACCESS_REPLY(1))
{
var req = new AUTHZ_ACCESS_REQUEST((uint)ACCESS_MASK.MAXIMUM_ALLOWED);
var b = AuthzAccessCheck(AuthzAccessCheckFlags.NONE, hCtx, req, hEvt, psd, null, 0, reply, out var hRes);
if (!b) TestContext.WriteLine($"AuthzAccessCheck:{Win32Error.GetLastError()}");
Assert.That(b);
Assert.That(reply.GrantedAccessMask, Is.Not.EqualTo(IntPtr.Zero));
TestContext.WriteLine($"Access:{string.Join(",", reply.GrantedAccessMaskValues.Select(u => ((FileAccess)u).ToString()))}");
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
using SafeAUTHZ_AUDIT_EVENT_HANDLE hEvt = GetAuthzInitializeObjectAccessAuditEvent();
using SafePSECURITY_DESCRIPTOR psd = AdvApi32Tests.GetSD(TestCaseSources.SmallFile);
using AUTHZ_ACCESS_REPLY reply = new(1);
AUTHZ_ACCESS_REQUEST req = new(ACCESS_MASK.MAXIMUM_ALLOWED);
Assert.That(AuthzAccessCheck(AuthzAccessCheckFlags.NONE, hCtx, req, hEvt, psd, null, 0, reply, out SafeAUTHZ_ACCESS_CHECK_RESULTS_HANDLE hRes), ResultIs.Successful);
Assert.That(reply.GrantedAccessMask, Is.Not.EqualTo(IntPtr.Zero));
TestContext.WriteLine($"Access:{string.Join(",", reply.GrantedAccessMaskValues.Select(u => ((FileAccess)u).ToString()))}");
Assert.That(AuthzCachedAccessCheck(0, hRes, req, default, reply), Is.True);
Assert.That(AuthzCachedAccessCheck(0, hRes, req, default, reply), Is.True);
hRes.Dispose();
Assert.That(hRes.IsClosed);
hRes.Dispose();
Assert.That(hRes.IsClosed);
Assert.That(AuthzFreeCentralAccessPolicyCache(), Is.True);
}
Assert.That(AuthzFreeCentralAccessPolicyCache(), Is.True);
}
[Test]
public void AuthzGetInformationFromContextTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
{
var buf = GetCtxInfo(hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoGroupsSids);
var tg = buf.ToStructure<TOKEN_GROUPS>();
Assert.That(tg.GroupCount, Is.GreaterThan(0));
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
SafeHGlobalHandle buf = GetCtxInfo(hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoGroupsSids);
TOKEN_GROUPS tg = buf.ToStructure<TOKEN_GROUPS>();
Assert.That(tg.GroupCount, Is.GreaterThan(0));
buf = GetCtxInfo(hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoUserClaims);
var ai = AUTHZ_SECURITY_ATTRIBUTES_INFORMATION.FromPtr((IntPtr)buf);
if (ai == null) return;
Assert.That(ai.Version, Is.EqualTo(1));
TestContext.WriteLine($"AuthzGetInformationFromContext(AuthzContextInfoUserClaims)={ai.AttributeCount}");
buf = GetCtxInfo(hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoUserClaims);
AUTHZ_SECURITY_ATTRIBUTES_INFORMATION ai = AUTHZ_SECURITY_ATTRIBUTES_INFORMATION.FromPtr(buf);
if (ai == null)
{
return;
}
Assert.That(ai.Version, Is.EqualTo(1));
TestContext.WriteLine($"AuthzGetInformationFromContext(AuthzContextInfoUserClaims)={ai.AttributeCount}");
}
[Test]
public void AuthzInitializeCompoundContextTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
using (var hDevCtx = GetTokenAuthContext(hRM))
{
var b = AuthzInitializeCompoundContext(hCtx, hDevCtx, out var hCompCtx);
if (!b) TestContext.WriteLine($"AuthzAccessCheck:{Win32Error.GetLastError()}");
Assert.That(b);
Assert.That(!hCompCtx.IsInvalid);
}
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hDevCtx = GetTokenAuthContext(hRM);
Assert.That(AuthzInitializeCompoundContext(hCtx, hDevCtx, out SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCompCtx), ResultIs.Successful);
Assert.That(!hCompCtx.IsInvalid);
}
[Test]
public void AuthzInitializeContextFromAuthzContextTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
{
var b = AuthzInitializeContextFromAuthzContext(0, hCtx, long.MaxValue, new LUID(), new IntPtr(2), out var hNewCtx);
Assert.That(b, Is.True);
}
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
Assert.That(AuthzInitializeContextFromAuthzContext(0, hCtx, long.MaxValue, new LUID(), new IntPtr(2), out SafeAUTHZ_CLIENT_CONTEXT_HANDLE hNewCtx), ResultIs.Successful);
}
[Test]
public void AuthzInitializeContextFromSidTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
{
Assert.That(hCtx.IsInvalid, Is.False);
}
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
Assert.That(hCtx.IsInvalid, Is.False);
}
[Test]
public void AuthzInitializeContextFromTokenTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hDevCtx = GetTokenAuthContext(hRM))
{
Assert.That(hDevCtx.IsInvalid, Is.False);
}
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hDevCtx = GetTokenAuthContext(hRM);
Assert.That(hDevCtx.IsInvalid, Is.False);
}
[Test]
public void AuthzInitializeObjectAccessAuditEventTest()
{
using (var hEvent = GetAuthzInitializeObjectAccessAuditEvent())
Assert.That(hEvent.IsInvalid, Is.False);
using SafeAUTHZ_AUDIT_EVENT_HANDLE hEvent = GetAuthzInitializeObjectAccessAuditEvent();
Assert.That(hEvent.IsInvalid, Is.False);
}
[Test]
public void AuthzInitializeObjectAccessAuditEvent2Test()
{
var b = AuthzInitializeObjectAccessAuditEvent2(0, default, "", "", "", "", "", out var hEvent);
if (!b) TestContext.WriteLine($"AuthzInitializeObjectAccessAuditEvent2:{Win32Error.GetLastError()}");
Assert.That(b, Is.True);
Assert.That(AuthzInitializeObjectAccessAuditEvent2(0, default, "", "", "", "", "", out SafeAUTHZ_AUDIT_EVENT_HANDLE hEvent), ResultIs.Successful);
Assert.That(hEvent.IsInvalid, Is.False);
}
[Test]
public void AuthzInitializeRemoteResourceManagerTest()
{
var client = new AUTHZ_RPC_INIT_INFO_CLIENT
AUTHZ_RPC_INIT_INFO_CLIENT client = new()
{
version = AUTHZ_RPC_INIT_INFO_CLIENT.AUTHZ_RPC_INIT_INFO_CLIENT_VERSION_V1,
ObjectUuid = "5fc860e0-6f6e-4fc2-83cd-46324f25e90b",
@ -214,173 +179,172 @@ namespace Vanara.PInvoke.Tests
NetworkAddr = "192.168.0.1",
Endpoint = "192.168.0.202[80]"
};
var b = AuthzInitializeRemoteResourceManager(client, out var hResMgr);
if (!b) TestContext.WriteLine($"AuthzInitializeResourceManager:{Win32Error.GetLastError()}");
Assert.That(b);
Assert.That(AuthzInitializeRemoteResourceManager(client, out SafeAUTHZ_RESOURCE_MANAGER_HANDLE hResMgr), ResultIs.Successful);
Assert.That(!hResMgr.IsInvalid);
}
[Test]
public void AuthzInitializeResourceManagerTest()
{
GetAuthzInitializeResourceManager();
}
public void AuthzInitializeResourceManagerTest() => GetAuthzInitializeResourceManager();
[Test]
public void AuthzInitializeResourceManagerExTest()
{
var info = new AUTHZ_INIT_INFO
AUTHZ_INIT_INFO info = new()
{
version = AUTHZ_INIT_INFO.AUTHZ_INIT_INFO_VERSION_V1
};
var b = AuthzInitializeResourceManagerEx(AuthzResourceManagerFlags.AUTHZ_RM_FLAG_NO_AUDIT, info, out var hResMgr);
if (!b) TestContext.WriteLine($"AuthzInitializeResourceManager:{Win32Error.GetLastError()}");
Assert.That(b);
Assert.That(AuthzInitializeResourceManagerEx(AuthzResourceManagerFlags.AUTHZ_RM_FLAG_NO_AUDIT, info, out SafeAUTHZ_RESOURCE_MANAGER_HANDLE hResMgr), ResultIs.Successful);
Assert.That(!hResMgr.IsInvalid);
}
[Test]
public void AuthzModifyClaimsTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
{
var attrs = new AUTHZ_SECURITY_ATTRIBUTES_INFORMATION(new[] { new AUTHZ_SECURITY_ATTRIBUTE_V1("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", Environment.UserName) });
var b = AuthzModifyClaims(hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoUserClaims, new[] { AUTHZ_SECURITY_ATTRIBUTE_OPERATION.AUTHZ_SECURITY_ATTRIBUTE_OPERATION_ADD }, attrs);
if (!b) TestContext.WriteLine($"AuthzModifyClaims:{Win32Error.GetLastError()}");
Assert.That(b);
}
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
AUTHZ_SECURITY_ATTRIBUTES_INFORMATION attrs = new(new[] { new AUTHZ_SECURITY_ATTRIBUTE_V1("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", Environment.UserName) });
Assert.That(AuthzModifyClaims(hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoUserClaims, new[] { AUTHZ_SECURITY_ATTRIBUTE_OPERATION.AUTHZ_SECURITY_ATTRIBUTE_OPERATION_ADD }, attrs), ResultIs.Successful);
}
[Test]
public void AuthzModifySecurityAttributesTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
{
var attrs = new AUTHZ_SECURITY_ATTRIBUTES_INFORMATION(new[] { new AUTHZ_SECURITY_ATTRIBUTE_V1("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", Environment.UserName) });
var b = AuthzModifySecurityAttributes(hCtx, new[] { AUTHZ_SECURITY_ATTRIBUTE_OPERATION.AUTHZ_SECURITY_ATTRIBUTE_OPERATION_ADD }, attrs);
if (!b) TestContext.WriteLine($"AuthzModifySecurityAttributes:{Win32Error.GetLastError()}");
Assert.That(b);
}
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
AUTHZ_SECURITY_ATTRIBUTES_INFORMATION attrs = new(new[] { new AUTHZ_SECURITY_ATTRIBUTE_V1("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name", Environment.UserName) });
Assert.That(AuthzModifySecurityAttributes(hCtx, new[] { AUTHZ_SECURITY_ATTRIBUTE_OPERATION.AUTHZ_SECURITY_ATTRIBUTE_OPERATION_ADD }, attrs), ResultIs.Successful);
}
[Test]
public void AuthzModifySidsTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
{
var tg = new TOKEN_GROUPS(1);
var psid = new SafePSID("S-1-5-32-551");
tg.Groups[0] = new SID_AND_ATTRIBUTES { Attributes = (uint)GroupAttributes.SE_GROUP_ENABLED, Sid = (IntPtr)psid };
var b = AuthzModifySids(hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoGroupsSids, new[] { AUTHZ_SID_OPERATION.AUTHZ_SID_OPERATION_ADD }, in tg);
if (!b) TestContext.WriteLine($"AuthzModifySids:{Win32Error.GetLastError()}");
Assert.That(b);
}
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
TOKEN_GROUPS tg = new(1);
SafePSID psid = new("S-1-5-32-551");
tg.Groups[0] = new SID_AND_ATTRIBUTES { Attributes = (uint)GroupAttributes.SE_GROUP_ENABLED, Sid = (IntPtr)psid };
Assert.That(AuthzModifySids(hCtx, AUTHZ_CONTEXT_INFORMATION_CLASS.AuthzContextInfoGroupsSids, new[] { AUTHZ_SID_OPERATION.AUTHZ_SID_OPERATION_ADD }, in tg), ResultIs.Successful);
}
[Test]
public void AuthzOpenObjectAuditTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
using (var hEvt = GetAuthzInitializeObjectAccessAuditEvent())
using (var psd = AdvApi32Tests.GetSD(TestCaseSources.SmallFile))
using (var reply = new AUTHZ_ACCESS_REPLY(1))
{
var req = new AUTHZ_ACCESS_REQUEST((uint)ACCESS_MASK.MAXIMUM_ALLOWED);
var b = AuthzOpenObjectAudit(0, hCtx, req, hEvt, psd, null, 0, reply);
if (!b) TestContext.WriteLine($"AuthzOpenObjectAudit:{Win32Error.GetLastError()}");
Assert.That(b, Is.True);
}
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
using SafeAUTHZ_AUDIT_EVENT_HANDLE hEvt = GetAuthzInitializeObjectAccessAuditEvent();
using SafePSECURITY_DESCRIPTOR psd = AdvApi32Tests.GetSD(TestCaseSources.SmallFile);
using AUTHZ_ACCESS_REPLY reply = new(1);
AUTHZ_ACCESS_REQUEST req = new(ACCESS_MASK.MAXIMUM_ALLOWED);
Assert.That(AuthzOpenObjectAudit(0, hCtx, req, hEvt, psd, null, 0, reply), ResultIs.Successful);
}
[Test]
public void AuthzRegisterCapChangeNotificationTest()
{
Assert.That(AuthzRegisterCapChangeNotification(out var hSub, callback, new IntPtr(2)), Is.True);
Assert.That(AuthzRegisterCapChangeNotification(out SafeAUTHZ_CAP_CHANGE_SUBSCRIPTION_HANDLE hSub, callback, new IntPtr(2)), Is.True);
// TODO: Find way to make something happen
Assert.That(AuthzUnregisterCapChangeNotification(hSub), Is.True);
uint callback(IntPtr lpThreadParameter) { Assert.That(lpThreadParameter.ToInt32(), Is.EqualTo(2)); return 0; }
static uint callback(IntPtr lpThreadParameter) { Assert.That(lpThreadParameter.ToInt32(), Is.EqualTo(2)); return 0; }
}
[Test]
public void SafeAUTHZ_SOURCE_SCHEMA_REGISTRATIONTest()
public void AuthzReportSecurityEventTest()
{
const string eventSource = "TestEventSource";
var guid = Guid.NewGuid();
using (var srcReg = new SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION { szEventSourceName = eventSource, szEventAccessStringsFile = @"%SystemRoot%\System32\MsObjs.dll", szObjectTypeName = "Obj1", pProviderGuid = guid })
const int eventId = 4624;
const string eventFile = "Some random string";
const string eventSource = "TestAddEventSource";
using (new ElevPriv("SeAuditPrivilege"))
{
var nSrc = (AUTHZ_SOURCE_SCHEMA_REGISTRATION)srcReg;
Assert.That(nSrc.szEventSourceName.ToString(), Is.EqualTo(eventSource));
Assert.That(nSrc.pProviderGuid, Is.Not.EqualTo(IntPtr.Zero));
Assert.That(nSrc.dwObjectTypeNameCount, Is.EqualTo(1U));
Assert.That(nSrc.ObjectTypeNames.szObjectTypeName.ToString(), Is.EqualTo("Obj1"));
Assert.That(null, Is.EqualTo((string)nSrc.szEventMessageFile));
using (var srcReg2 = new SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION(nSrc))
AUTHZ_SOURCE_SCHEMA_REGISTRATION srcReg = new()
{
Assert.That(srcReg2.szEventSourceName, Is.EqualTo(eventSource));
Assert.That(srcReg2.pProviderGuid.HasValue, Is.True);
Assert.That(srcReg2.pProviderGuid.Value, Is.EqualTo(guid));
Assert.That(srcReg2.szObjectTypeName, Is.EqualTo("Obj1"));
Assert.That(srcReg2.szEventMessageFile, Is.Null);
dwFlags = SOURCE_SCHEMA_REGISTRATION_FLAGS.AUTHZ_ALLOW_MULTIPLE_SOURCE_INSTANCES,
szEventSourceName = eventSource,
szEventMessageFile = eventFile,
szEventAccessStringsFile = eventFile,
};
Assert.IsTrue(AuthzInstallSecurityEventSource(0, srcReg) || Win32Error.GetLastError() == Win32Error.ERROR_OBJECT_ALREADY_EXISTS);
Assert.That(AuthzRegisterSecurityEventSource(0, eventSource, out SafeAUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEvtProv), ResultIs.Successful);
try
{
Assert.That(AuthzReportSecurityEvent(APF.APF_AuditSuccess, hEvtProv, eventId, PSID.NULL, 6, __arglist(
AUDIT_PARAM_TYPE.APT_String, "Testing",
AUDIT_PARAM_TYPE.APT_Ulong, 123,
AUDIT_PARAM_TYPE.APT_Guid, (IntPtr)new SafeCoTaskMemStruct<Guid>(Guid.NewGuid()),
AUDIT_PARAM_TYPE.APT_Sid, (IntPtr)SafePSID.Current,
AUDIT_PARAM_TYPE.APT_Int64, long.MaxValue - 1,
AUDIT_PARAM_TYPE.APT_Time, DateTime.Now.ToFileTime()
)), ResultIs.Successful);
}
finally { Assert.That(() => hEvtProv.Dispose(), Throws.Nothing); }
}
}
[Test]
public void AuthzRegisterSecurityEventSourceTest()
public void AuthzReportSecurityEventFromParamsTest()
{
const string eventSource = "TestEventSource";
const int eventId = 4624;
const string eventFile = "Some random string";
const string eventSource = "TestAddEventSource";
using (new ElevPriv("SeAuditPrivilege"))
{
var srcReg = new SafeAUTHZ_SOURCE_SCHEMA_REGISTRATION { szEventSourceName = eventSource, szEventAccessStringsFile = @"%SystemRoot%\System32\MsObjs.dll", szObjectTypeName = "Obj1", pProviderGuid = Guid.NewGuid() };
Assert.That(AuthzInstallSecurityEventSource(0, srcReg), Is.True);
var b = AuthzRegisterSecurityEventSource(0, eventSource, out var hEvtProv);
if (!b) TestContext.WriteLine($"AuthzRegisterSecurityEventSource:{Win32Error.GetLastError()}");
//Assert.That(b, Is.True); This is due to a Domain-defined Local policy
if (b)
AUTHZ_SOURCE_SCHEMA_REGISTRATION srcReg = new()
{
using (var data = new SafeHGlobalHandle("Testing"))
using (var mem = SafeHGlobalHandle.CreateFromStructure(new AUDIT_PARAM { Type = AUDIT_PARAM_TYPE.APT_String, Data0 = (IntPtr)data }))
{
var ap = new AUDIT_PARAMS { Count = 1, Parameters = (IntPtr)mem };
b = AuthzReportSecurityEventFromParams(0, hEvtProv, 4624, PSID.NULL, ap);
if (!b) TestContext.WriteLine($"AuthzReportSecurityEvent:{Win32Error.GetLastError()}");
Assert.That(b, Is.True);
}
dwFlags = SOURCE_SCHEMA_REGISTRATION_FLAGS.AUTHZ_ALLOW_MULTIPLE_SOURCE_INSTANCES,
szEventSourceName = eventSource,
szEventMessageFile = eventFile,
szEventAccessStringsFile = eventFile,
};
Assert.IsTrue(AuthzInstallSecurityEventSource(0, srcReg) || Win32Error.GetLastError() == Win32Error.ERROR_OBJECT_ALREADY_EXISTS);
b = AuthzReportSecurityEvent(APF.APF_AuditSuccess, hEvtProv, 4624, PSID.NULL, 1, __arglist(AUDIT_PARAM_TYPE.APT_String, "Testing"));
if (!b) TestContext.WriteLine($"AuthzReportSecurityEvent:{Win32Error.GetLastError()}");
Assert.That(b, Is.True);
Assert.That(AuthzUnregisterSecurityEventSource(0, hEvtProv), Is.True);
Assert.That(AuthzRegisterSecurityEventSource(0, eventSource, out SafeAUTHZ_SECURITY_EVENT_PROVIDER_HANDLE hEvtProv), ResultIs.Successful);
try
{
using SafeCoTaskMemString data = new("Testing");
//using SafeCoTaskMemString name = new("MyName");
using SafeNativeArray<AUDIT_PARAM> mem = new(new[] { new AUDIT_PARAM { Type = AUDIT_PARAM_TYPE.APT_String, Data0 = data/*, Data1 = name*/ } });
AUDIT_PARAMS ap = new() { Count = 1, Parameters = mem };
Assert.That(AuthzReportSecurityEventFromParams(0, hEvtProv, eventId, PSID.NULL, ap), ResultIs.Successful);
}
finally { Assert.That(() => hEvtProv.Dispose(), Throws.Nothing); }
}
}
[Test]
public void AuthzInstallSecurityEventSourceTest()
{
const string eventFile = "Some random string";
const string eventSource = "InstTestEventSource";
using (new ElevPriv("SeAuditPrivilege"))
{
AUTHZ_SOURCE_SCHEMA_REGISTRATION srcReg = new()
{
dwFlags = SOURCE_SCHEMA_REGISTRATION_FLAGS.AUTHZ_ALLOW_MULTIPLE_SOURCE_INSTANCES,
szEventSourceName = eventSource,
szEventMessageFile = eventFile,
szEventAccessStringsFile = eventFile,
};
Assert.That(AuthzInstallSecurityEventSource(0, srcReg), ResultIs.Successful);
Assert.That(AuthzUninstallSecurityEventSource(0, eventSource), Is.True);
}
}
// TODO: Figure out how AuthzSetAppContainerInformation works
// [Test]
public void AuthzSetAppContainerInformationTest()
public void AuthzSetAppContainerInformationTest()
{
using (var hRM = GetAuthzInitializeResourceManager())
using (var hCtx = GetCurrentUserAuthContext(hRM))
using (var localSid = ConvertStringSidToSid("S-1-2-0"))
using (var hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_ALL_ACCESS))
{
var i = hTok.GetInfo<TOKEN_APPCONTAINER_INFORMATION>(TOKEN_INFORMATION_CLASS.TokenAppContainerSid);
//var sids = new SID_AND_ATTRIBUTES(localSid, (uint)GroupAttributes.SE_GROUP_ENABLED);
//var b = AuthzSetAppContainerInformation(hCtx, i.TokenAppContainer, 1, new[] { sids });
var b = AuthzSetAppContainerInformation(hCtx, i.TokenAppContainer, 0, null);
if (!b) TestContext.WriteLine($"AuthzSetAppContainerInformation:{Win32Error.GetLastError()}");
Assert.That(b, Is.True);
}
using SafeAUTHZ_RESOURCE_MANAGER_HANDLE hRM = GetAuthzInitializeResourceManager();
using SafeAUTHZ_CLIENT_CONTEXT_HANDLE hCtx = GetCurrentUserAuthContext(hRM);
using SafePSID localSid = ConvertStringSidToSid("S-1-2-0");
using SafeHTOKEN hTok = SafeHTOKEN.FromProcess(GetCurrentProcess(), TokenAccess.TOKEN_ALL_ACCESS);
TOKEN_APPCONTAINER_INFORMATION i = hTok.GetInfo<TOKEN_APPCONTAINER_INFORMATION>(TOKEN_INFORMATION_CLASS.TokenAppContainerSid);
//var sids = new SID_AND_ATTRIBUTES(localSid, (uint)GroupAttributes.SE_GROUP_ENABLED);
//var b = AuthzSetAppContainerInformation(hCtx, i.TokenAppContainer, 1, new[] { sids });
Assert.That(AuthzSetAppContainerInformation(hCtx, i.TokenAppContainer, 0, null), ResultIs.Successful);
}
}
}