summaryrefslogtreecommitdiffstats
path: root/private/ntos/se/sepaudit.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/se/sepaudit.c2629
1 files changed, 2629 insertions, 0 deletions
diff --git a/private/ntos/se/sepaudit.c b/private/ntos/se/sepaudit.c
new file mode 100644
index 000000000..6fb6fc17d
--- /dev/null
+++ b/private/ntos/se/sepaudit.c
@@ -0,0 +1,2629 @@
+/*++
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ sepaudit.c
+
+Abstract:
+
+ This Module implements the audit and alarm procedures that are
+ private to the security component.
+
+Author:
+
+ Robert Reichel (robertre) September 10, 1991
+
+Environment:
+
+ Kernel Mode
+
+Revision History:
+
+--*/
+
+#include <nt.h>
+#include <ntlsa.h>
+#include <msaudite.h>
+#include "tokenp.h"
+#include "adt.h"
+#include "adtp.h"
+
+
+#ifdef ALLOC_PRAGMA
+#pragma alloc_text(PAGE,SeAuditHandleDuplication)
+// #pragma alloc_text(PAGE,SepAdtAuditThisEvent)
+#pragma alloc_text(PAGE,SepAdtPrivilegeObjectAuditAlarm)
+#pragma alloc_text(PAGE,SepAdtPrivilegedServiceAuditAlarm)
+#pragma alloc_text(PAGE,SepAdtOpenObjectAuditAlarm)
+#pragma alloc_text(PAGE,SepAdtOpenObjectForDeleteAuditAlarm)
+#pragma alloc_text(PAGE,SepAdtHandleAuditAlarm)
+#pragma alloc_text(PAGE,SepAdtObjectReferenceAuditAlarm)
+#pragma alloc_text(PAGE,SepQueryNameString)
+#pragma alloc_text(PAGE,SepQueryTypeString)
+#pragma alloc_text(PAGE,SeAuditProcessCreation)
+#pragma alloc_text(PAGE,SeAuditProcessExit)
+#pragma alloc_text(PAGE,SepAdtGenerateDiscardAudit)
+#endif
+
+
+#define SepSetParmTypeSid( AuditParameters, Index, Sid ) \
+ { \
+ (AuditParameters).Parameters[(Index)].Type = SeAdtParmTypeSid; \
+ (AuditParameters).Parameters[(Index)].Length = RtlLengthSid( (Sid) ); \
+ (AuditParameters).Parameters[(Index)].Address = (Sid); \
+ }
+
+
+#define SepSetParmTypeString( AuditParameters, Index, String ) \
+ { \
+ (AuditParameters).Parameters[(Index)].Type = SeAdtParmTypeString; \
+ (AuditParameters).Parameters[(Index)].Length = \
+ sizeof(UNICODE_STRING)+(String)->Length; \
+ (AuditParameters).Parameters[(Index)].Address = (String); \
+ }
+
+
+#define SepSetParmTypeFileSpec( AuditParameters, Index, String ) \
+ { \
+ (AuditParameters).Parameters[(Index)].Type = SeAdtParmTypeFileSpec; \
+ (AuditParameters).Parameters[(Index)].Length = \
+ sizeof(UNICODE_STRING)+(String)->Length; \
+ (AuditParameters).Parameters[(Index)].Address = (String); \
+ }
+
+#define SepSetParmTypeUlong( AuditParameters, Index, Ulong ) \
+ { \
+ (AuditParameters).Parameters[(Index)].Type = SeAdtParmTypeUlong; \
+ (AuditParameters).Parameters[(Index)].Length = sizeof( (Ulong) ); \
+ (AuditParameters).Parameters[(Index)].Data[0] = (ULONG)(Ulong); \
+ }
+
+#define SepSetParmTypeNoLogon( AuditParameters, Index ) \
+ { \
+ (AuditParameters).Parameters[(Index)].Type = SeAdtParmTypeNoLogonId; \
+ }
+
+#define SepSetParmTypeLogonId( AuditParameters, Index, LogonId ) \
+ { \
+ LUID UNALIGNED * TmpLuid; \
+ \
+ (AuditParameters).Parameters[(Index)].Type = SeAdtParmTypeLogonId; \
+ (AuditParameters).Parameters[(Index)].Length = sizeof( (LogonId) ); \
+ TmpLuid = (LUID UNALIGNED *)(&(AuditParameters).Parameters[(Index)].Data[0]); \
+ *TmpLuid = (LogonId); \
+ }
+
+#define SepSetParmTypeAccessMask( AuditParameters, Index, AccessMask, ObjectTypeIndex ) \
+ { \
+ (AuditParameters).Parameters[(Index)].Type = SeAdtParmTypeAccessMask; \
+ (AuditParameters).Parameters[(Index)].Length = sizeof( ACCESS_MASK ); \
+ (AuditParameters).Parameters[(Index)].Data[0] = (AccessMask); \
+ (AuditParameters).Parameters[(Index)].Data[1] = (ObjectTypeIndex); \
+ }
+
+#define SepSetParmTypePrivileges( AuditParameters, Index, Privileges ) \
+ { \
+ (AuditParameters).Parameters[(Index)].Type = SeAdtParmTypePrivs; \
+ (AuditParameters).Parameters[(Index)].Length = SepPrivilegeSetSize( (Privileges) ); \
+ (AuditParameters).Parameters[(Index)].Address = (Privileges); \
+ }
+
+
+
+BOOLEAN
+SepAdtPrivilegeObjectAuditAlarm (
+ IN PUNICODE_STRING CapturedSubsystemName OPTIONAL,
+ IN PVOID HandleId,
+ IN PTOKEN ClientToken OPTIONAL,
+ IN PTOKEN PrimaryToken,
+ IN PVOID ProcessId,
+ IN ACCESS_MASK DesiredAccess,
+ IN PPRIVILEGE_SET CapturedPrivileges,
+ IN BOOLEAN AccessGranted
+ )
+
+/*++
+
+Routine Description:
+
+ Implements NtPrivilegeObjectAuditAlarm after parameters have been
+ captured.
+
+ This routine is used to generate audit and alarm messages when an
+ attempt is made to perform privileged operations on a protected
+ subsystem object after the object is already opened. This routine may
+ result in several messages being generated and sent to Port objects.
+ This may result in a significant latency before returning. Design of
+ routines that must call this routine must take this potential latency
+ into account. This may have an impact on the approach taken for data
+ structure mutex locking, for example.
+
+ This API requires the caller have SeTcbPrivilege privilege. The test
+ for this privilege is always against the primary token of the calling
+ process, allowing the caller to be impersonating a client during the
+ call with no ill effects.
+
+ This routine will create an SE_ADT_PARAMETERS array organized as follows:
+
+ Parameter[0] - User Sid
+
+ Parameter[1] - Subsystem name (if available)
+
+ Parameter[2] - New handle ID
+
+ Parameter[3] - Subject's process id
+
+ Parameter[4] - Subject's primary authentication ID
+
+ Parameter[5] - Subject's client authentication ID
+
+ Parameter[6] - Privileges used for open
+
+Arguments:
+
+ CapturedSubsystemName - Supplies a name string identifying the
+ subsystem calling the routine.
+
+ HandleId - A unique value representing the client's handle to the
+ object.
+
+ ClientToken - Optionally provides a pointer to the client token
+ (only if the caller is currently impersonating)
+
+ PrimaryToken - Provides a pointer to the caller's primary token.
+
+ DesiredAccess - The desired access mask. This mask must have been
+ previously mapped to contain no generic accesses.
+
+ CapturedPrivileges - The set of privileges required for the requested
+ operation. Those privileges that were held by the subject are
+ marked using the UsedForAccess flag of the attributes
+ associated with each privilege.
+
+ AccessGranted - Indicates whether the requested access was granted or
+ not. A value of TRUE indicates the access was granted. A value of
+ FALSE indicates the access was not granted.
+
+Return value:
+
+--*/
+{
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ PSID CapturedUserSid;
+ LUID ClientAuthenticationId;
+ LUID PrimaryAuthenticationId;
+
+ PAGED_CODE();
+
+ //
+ // Determine if we are auditing the use of privileges
+ //
+
+ if ( SepAdtAuditThisEvent( AuditCategoryPrivilegeUse, &AccessGranted ) &&
+ SepFilterPrivilegeAudits( CapturedPrivileges )) {
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ CapturedUserSid = SepTokenUserSid( ClientToken );
+ ClientAuthenticationId = SepTokenAuthenticationId( ClientToken );
+
+ } else {
+
+ CapturedUserSid = SepTokenUserSid( PrimaryToken );
+ }
+
+ if ( RtlEqualSid( SeLocalSystemSid, CapturedUserSid )) {
+
+ return (FALSE);
+ }
+
+ PrimaryAuthenticationId = SepTokenAuthenticationId( PrimaryToken );
+
+ //
+ // A completely zero'd entry will be interpreted
+ // as a "null string" or not supplied parameter.
+ //
+ // Initializing the entire array up front will allow
+ // us to avoid filling in each not supplied entry.
+ //
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_PRIVILEGE_USE;
+ AuditParameters.AuditId = SE_AUDITID_PRIVILEGED_OBJECT;
+ AuditParameters.ParameterCount = 0;
+
+ if ( AccessGranted ) {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+ } else {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_FAILURE;
+ }
+
+ //
+ // Parameter[0] - User Sid
+ //
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, CapturedUserSid );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[1] - Subsystem name (if available)
+ //
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[1] - Subsystem name (if available)
+ //
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[2] - New handle ID
+ //
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, HandleId );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[3] - Subject's process id
+ //
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, ProcessId );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[4] - Subject's primary authentication ID
+ //
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, PrimaryAuthenticationId );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[5] - Subject's client authentication ID
+ //
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, ClientAuthenticationId );
+
+ } else {
+
+ SepSetParmTypeNoLogon( AuditParameters, AuditParameters.ParameterCount );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[6] - Privileges used for open
+ //
+
+ if ( (CapturedPrivileges != NULL) && (CapturedPrivileges->PrivilegeCount > 0) ) {
+
+ SepSetParmTypePrivileges( AuditParameters, AuditParameters.ParameterCount, CapturedPrivileges );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ return( TRUE );
+
+ }
+
+ return( FALSE );
+}
+
+
+VOID
+SepAdtPrivilegedServiceAuditAlarm (
+ IN PUNICODE_STRING CapturedSubsystemName,
+ IN PUNICODE_STRING CapturedServiceName,
+ IN PTOKEN ClientToken OPTIONAL,
+ IN PTOKEN PrimaryToken,
+ IN PPRIVILEGE_SET CapturedPrivileges,
+ IN BOOLEAN AccessGranted
+ )
+
+/*++
+
+Routine Description:
+
+ This routine is the active part of NtPrivilegedServiceAuditAlarm.
+
+ This routine is used to generate audit and alarm messages when an
+ attempt is made to perform privileged system service operations. This
+ routine may result in several messages being generated and sent to Port
+ objects. This may result in a significant latency before returning.
+ Design of routines that must call this routine must take this potential
+ latency into account. This may have an impact on the approach taken
+ for data structure mutex locking, for example.
+
+ This API requires the caller have SeTcbPrivilege privilege. The test
+ for this privilege is always against the primary token of the calling
+ process, allowing the caller to be impersonating a client during the
+ call with no ill effects. The test for this privilege is assumed to
+ have occurred at a higher level.
+
+ This routine will create an SE_ADT_PARAMETERS array organized as follows:
+
+ Parameter[0] - User Sid
+
+ Parameter[1] - Subsystem name (if available)
+
+ Parameter[2] - Subject's primary authentication ID
+
+ Parameter[3] - Subject's client authentication ID
+
+ Parameter[4] - Privileges used for open
+
+Arguments:
+
+ SubsystemName - Supplies a name string identifying the subsystem
+ calling the routine.
+
+ ServiceName - Supplies a name of the privileged subsystem service. For
+ example, "RESET RUNTIME LOCAL SECURITY POLICY" might be specified
+ by a Local Security Authority service used to update the local
+ security policy database.
+
+ ClientToken - Optionally provides a pointer to the client token
+ (only if the caller is currently impersonating)
+
+ PrimaryToken - Provides a pointer to the caller's primary token.
+
+ Privileges - Points to a set of privileges required to perform the
+ privileged operation. Those privileges that were held by the
+ subject are marked using the UsedForAccess flag of the
+ attributes associated with each privilege.
+
+ AccessGranted - Indicates whether the requested access was granted or
+ not. A value of TRUE indicates the access was granted. A value of
+ FALSE indicates the access was not granted.
+
+
+Return value:
+
+
+--*/
+
+{
+
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ PSID CapturedUserSid;
+ LUID ClientAuthenticationId;
+ LUID PrimaryAuthenticationId;
+ PUNICODE_STRING SubsystemName;
+
+ PAGED_CODE();
+
+ //
+ // Determine if we are auditing privileged services
+ //
+
+ if ( SepAdtAuditThisEvent( AuditCategoryPrivilegeUse, &AccessGranted )) {
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ CapturedUserSid = SepTokenUserSid( ClientToken );
+ ClientAuthenticationId = SepTokenAuthenticationId( ClientToken );
+
+ } else {
+
+ CapturedUserSid = SepTokenUserSid( PrimaryToken );
+ }
+
+ PrimaryAuthenticationId = SepTokenAuthenticationId( PrimaryToken );
+
+ if ( !ARGUMENT_PRESENT( CapturedSubsystemName )) {
+
+ SubsystemName = &SeSubsystemName;
+
+ } else {
+
+ SubsystemName = CapturedSubsystemName;
+ }
+
+ //
+ // A completely zero'd entry will be interpreted
+ // as a "null string" or not supplied parameter.
+ //
+ // Initializing the entire array up front will allow
+ // us to avoid filling in each not supplied entry.
+ //
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_PRIVILEGE_USE;
+ AuditParameters.AuditId = SE_AUDITID_PRIVILEGED_SERVICE;
+ AuditParameters.ParameterCount = 0;
+
+ if ( AccessGranted ) {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+ } else {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_FAILURE;
+ }
+
+
+ //
+ // Parameter[0] - User Sid
+ //
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, CapturedUserSid );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[1] - Subsystem name (if available)
+ //
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, SubsystemName );
+
+ AuditParameters.ParameterCount++;
+
+
+ //
+ // Parameter[2] - Server
+ //
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, SubsystemName );
+
+ AuditParameters.ParameterCount++;
+
+
+ //
+ // Parameter[3] - Service name (if available)
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedServiceName )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedServiceName );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[3] - Subject's primary authentication ID
+ //
+
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, PrimaryAuthenticationId );
+
+ AuditParameters.ParameterCount++;
+
+
+ //
+ // Parameter[4] - Subject's client authentication ID
+ //
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, ClientAuthenticationId );
+
+ } else {
+
+ SepSetParmTypeNoLogon( AuditParameters, AuditParameters.ParameterCount );
+ }
+
+ AuditParameters.ParameterCount++;
+
+
+ //
+ // Parameter[5] - Privileges used for open
+ //
+
+
+ if ( (CapturedPrivileges != NULL) && (CapturedPrivileges->PrivilegeCount > 0) ) {
+
+ SepSetParmTypePrivileges( AuditParameters, AuditParameters.ParameterCount, CapturedPrivileges );
+ }
+
+ AuditParameters.ParameterCount++;
+
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ }
+
+}
+
+
+
+
+
+
+BOOLEAN
+SepAdtOpenObjectAuditAlarm (
+ IN PUNICODE_STRING CapturedSubsystemName,
+ IN PVOID *HandleId OPTIONAL,
+ IN PUNICODE_STRING CapturedObjectTypeName,
+ IN PVOID Object OPTIONAL,
+ IN PUNICODE_STRING CapturedObjectName OPTIONAL,
+ IN PTOKEN ClientToken OPTIONAL,
+ IN PTOKEN PrimaryToken,
+ IN ACCESS_MASK DesiredAccess,
+ IN ACCESS_MASK GrantedAccess,
+ IN PLUID OperationId,
+ IN PPRIVILEGE_SET CapturedPrivileges OPTIONAL,
+ IN BOOLEAN ObjectCreated,
+ IN BOOLEAN AccessGranted,
+ IN BOOLEAN GenerateAudit,
+ IN BOOLEAN GenerateAlarm,
+ IN HANDLE ProcessID
+ )
+
+/*++
+
+ Routine Description:
+
+ Implements NtOpenObjectAuditAlarm after parameters have been captured.
+
+ This routine is used to generate audit and alarm messages when an
+ attempt is made to access an existing protected subsystem object or
+ create a new one. This routine may result in several messages being
+ generated and sent to Port objects. This may result in a significant
+ latency before returning. Design of routines that must call this
+ routine must take this potential latency into account. This may have
+ an impact on the approach taken for data structure mutex locking, for
+ example. This API requires the caller have SeTcbPrivilege privilege.
+ The test for this privilege is always against the primary token of the
+ calling process, not the impersonation token of the thread.
+
+
+ This routine will create an SE_ADT_PARAMETERS array organized as follows:
+
+ Parameter[0] - User Sid
+
+ Parameter[1] - Subsystem name (if available)
+
+ Parameter[2] - Server name (if available)
+
+ Parameter[3] - Object Type Name
+
+ Parameter[4] - Object Name
+
+ Parameter[5] - New handle ID
+
+ Parameter[6] - Subject's process id
+
+ Parameter[7] - Subject's primary authentication ID
+
+ Parameter[8] - Subject's client authentication ID
+
+ Parameter[9] - DesiredAccess mask
+
+ Parameter[10] - Privileges used for open
+
+Arguments:
+
+ CapturedSubsystemName - Supplies a name string identifying the
+ subsystem calling the routine.
+
+ HandleId - A unique value representing the client's handle to the
+ object. If the access attempt was not successful (AccessGranted is
+ FALSE), then this parameter is ignored.
+
+ CapturedObjectTypeName - Supplies the name of the type of object being
+ accessed.
+
+ CapturedObjectName - Supplies the name of the object the client
+ accessed or attempted to access.
+
+ CapturedSecurityDescriptor - A pointer to the security descriptor of
+ the object being accessed.
+
+ ClientToken - Optionally provides a pointer to the client token
+ (only if the caller is currently impersonating)
+
+ PrimaryToken - Provides a pointer to the caller's primary token.
+
+ DesiredAccess - The desired access mask. This mask must have been
+ previously mapped to contain no generic accesses.
+
+ GrantedAccess - The mask of accesses that were actually granted.
+
+ CapturedPrivileges - Optionally points to a set of privileges that were
+ required for the access attempt. Those privileges that were held
+ by the subject are marked using the UsedForAccess flag of the
+ attributes associated with each privilege.
+
+ ObjectCreation - A boolean flag indicating whether the access will
+ result in a new object being created if granted. A value of TRUE
+ indicates an object will be created, FALSE indicates an existing
+ object will be opened.
+
+ AccessGranted - Indicates whether the requested access was granted or
+ not. A value of TRUE indicates the access was granted. A value of
+ FALSE indicates the access was not granted.
+
+ GenerateOnClose - Points to a boolean that is set by the audit
+ generation routine and must be passed to NtCloseObjectAuditAlarm()
+ when the object handle is closed.
+
+ GenerateAudit - Indicates if we should generate an audit for this operation.
+
+ GenerateAlarm - Indicates if we should generate an alarm for this operation.
+
+Return Value:
+
+ Returns TRUE if audit is generated, FALSE otherwise.
+
+--*/
+
+{
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ ULONG ObjectTypeIndex;
+ PSID CapturedUserSid;
+ LUID PrimaryAuthenticationId;
+ LUID ClientAuthenticationId;
+
+ PAGED_CODE();
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ CapturedUserSid = SepTokenUserSid( ClientToken );
+ ClientAuthenticationId = SepTokenAuthenticationId( ClientToken );
+
+ } else {
+
+ CapturedUserSid = SepTokenUserSid( PrimaryToken );
+ }
+
+ PrimaryAuthenticationId = SepTokenAuthenticationId( PrimaryToken );
+
+ //
+ // A completely zero'd entry will be interpreted
+ // as a "null string" or not supplied parameter.
+ //
+ // Initializing the entire array up front will allow
+ // us to avoid filling in each not supplied entry.
+ //
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_OBJECT_ACCESS;
+ AuditParameters.AuditId = SE_AUDITID_OPEN_HANDLE;
+ AuditParameters.ParameterCount = 0;
+
+ if ( AccessGranted ) {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+ } else {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_FAILURE;
+ }
+
+ //
+ // Parameter[0] - User Sid
+ //
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, CapturedUserSid );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[1] - Subsystem name (if available)
+ //
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[2] - Object Server (if available)
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedSubsystemName )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[3] - Object Type Name
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedObjectTypeName )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedObjectTypeName );
+ ObjectTypeIndex = AuditParameters.ParameterCount;
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[4] - Object Name
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedObjectName )) {
+
+ SepSetParmTypeFileSpec( AuditParameters, AuditParameters.ParameterCount, CapturedObjectName );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[5] - New handle ID
+ //
+
+ if ( ARGUMENT_PRESENT( HandleId )) {
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, *HandleId );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ if ( ARGUMENT_PRESENT( OperationId )) {
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, (*OperationId).HighPart );
+
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, (*OperationId).LowPart );
+
+ AuditParameters.ParameterCount++;
+
+ } else {
+
+ AuditParameters.ParameterCount += 2;
+ }
+
+ //
+ // Parameter[6] - Subject's process id
+ //
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, ProcessID );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[7] - Subject's primary authentication ID
+ //
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, PrimaryAuthenticationId );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[8] - Subject's client authentication ID
+ //
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, ClientAuthenticationId );
+
+ } else {
+
+ SepSetParmTypeNoLogon( AuditParameters, AuditParameters.ParameterCount );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[9] - DesiredAccess mask
+ //
+
+ if ( AccessGranted ) {
+
+ SepSetParmTypeAccessMask( AuditParameters, AuditParameters.ParameterCount, GrantedAccess, ObjectTypeIndex );
+
+ } else {
+
+ SepSetParmTypeAccessMask( AuditParameters, AuditParameters.ParameterCount, DesiredAccess, ObjectTypeIndex );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[10] - Privileges used for open
+ //
+
+ if ( (CapturedPrivileges != NULL) && (CapturedPrivileges->PrivilegeCount > 0) ) {
+
+ SepSetParmTypePrivileges( AuditParameters, AuditParameters.ParameterCount, CapturedPrivileges );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ return( TRUE );
+}
+
+
+BOOLEAN
+SepAdtOpenObjectForDeleteAuditAlarm (
+ IN PUNICODE_STRING CapturedSubsystemName,
+ IN PVOID *HandleId OPTIONAL,
+ IN PUNICODE_STRING CapturedObjectTypeName,
+ IN PVOID Object OPTIONAL,
+ IN PUNICODE_STRING CapturedObjectName OPTIONAL,
+ IN PTOKEN ClientToken OPTIONAL,
+ IN PTOKEN PrimaryToken,
+ IN ACCESS_MASK DesiredAccess,
+ IN ACCESS_MASK GrantedAccess,
+ IN PLUID OperationId,
+ IN PPRIVILEGE_SET CapturedPrivileges OPTIONAL,
+ IN BOOLEAN ObjectCreated,
+ IN BOOLEAN AccessGranted,
+ IN BOOLEAN GenerateAudit,
+ IN BOOLEAN GenerateAlarm,
+ IN HANDLE ProcessID
+ )
+
+/*++
+
+ Routine Description:
+
+ Implements SeOpenObjectForDeleteAuditAlarm after parameters have been
+ captured.
+
+ This routine is used to generate audit and alarm messages when an
+ attempt is made to access an existing protected subsystem object or
+ create a new one. This routine may result in several messages being
+ generated and sent to Port objects. This may result in a significant
+ latency before returning. Design of routines that must call this
+ routine must take this potential latency into account. This may have
+ an impact on the approach taken for data structure mutex locking, for
+ example. This API requires the caller have SeTcbPrivilege privilege.
+ The test for this privilege is always against the primary token of the
+ calling process, not the impersonation token of the thread.
+
+
+ This routine will create an SE_ADT_PARAMETERS array organized as follows:
+
+ Parameter[0] - User Sid
+
+ Parameter[1] - Subsystem name (if available)
+
+ Parameter[2] - Server name (if available)
+
+ Parameter[3] - Object Type Name
+
+ Parameter[4] - Object Name
+
+ Parameter[5] - New handle ID
+
+ Parameter[6] - Subject's process id
+
+ Parameter[7] - Subject's primary authentication ID
+
+ Parameter[8] - Subject's client authentication ID
+
+ Parameter[9] - DesiredAccess mask
+
+ Parameter[10] - Privileges used for open
+
+Arguments:
+
+ CapturedSubsystemName - Supplies a name string identifying the
+ subsystem calling the routine.
+
+ HandleId - A unique value representing the client's handle to the
+ object. If the access attempt was not successful (AccessGranted is
+ FALSE), then this parameter is ignored.
+
+ CapturedObjectTypeName - Supplies the name of the type of object being
+ accessed.
+
+ CapturedObjectName - Supplies the name of the object the client
+ accessed or attempted to access.
+
+ CapturedSecurityDescriptor - A pointer to the security descriptor of
+ the object being accessed.
+
+ ClientToken - Optionally provides a pointer to the client token
+ (only if the caller is currently impersonating)
+
+ PrimaryToken - Provides a pointer to the caller's primary token.
+
+ DesiredAccess - The desired access mask. This mask must have been
+ previously mapped to contain no generic accesses.
+
+ GrantedAccess - The mask of accesses that were actually granted.
+
+ CapturedPrivileges - Optionally points to a set of privileges that were
+ required for the access attempt. Those privileges that were held
+ by the subject are marked using the UsedForAccess flag of the
+ attributes associated with each privilege.
+
+ ObjectCreation - A boolean flag indicating whether the access will
+ result in a new object being created if granted. A value of TRUE
+ indicates an object will be created, FALSE indicates an existing
+ object will be opened.
+
+ AccessGranted - Indicates whether the requested access was granted or
+ not. A value of TRUE indicates the access was granted. A value of
+ FALSE indicates the access was not granted.
+
+ GenerateOnClose - Points to a boolean that is set by the audit
+ generation routine and must be passed to NtCloseObjectAuditAlarm()
+ when the object handle is closed.
+
+ GenerateAudit - Indicates if we should generate an audit for this operation.
+
+ GenerateAlarm - Indicates if we should generate an alarm for this operation.
+
+Return Value:
+
+ Returns TRUE if audit is generated, FALSE otherwise.
+
+--*/
+
+{
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ ULONG ObjectTypeIndex;
+ PSID CapturedUserSid;
+ LUID PrimaryAuthenticationId;
+ LUID ClientAuthenticationId;
+
+ PAGED_CODE();
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ CapturedUserSid = SepTokenUserSid( ClientToken );
+ ClientAuthenticationId = SepTokenAuthenticationId( ClientToken );
+
+ } else {
+
+ CapturedUserSid = SepTokenUserSid( PrimaryToken );
+ }
+
+ PrimaryAuthenticationId = SepTokenAuthenticationId( PrimaryToken );
+
+ //
+ // A completely zero'd entry will be interpreted
+ // as a "null string" or not supplied parameter.
+ //
+ // Initializing the entire array up front will allow
+ // us to avoid filling in each not supplied entry.
+ //
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_OBJECT_ACCESS;
+ AuditParameters.AuditId = SE_AUDITID_OPEN_OBJECT_FOR_DELETE;
+ AuditParameters.ParameterCount = 0;
+
+ if ( AccessGranted ) {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+ } else {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_FAILURE;
+ }
+
+ //
+ // Parameter[0] - User Sid
+ //
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, CapturedUserSid );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[1] - Subsystem name (if available)
+ //
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[2] - Object Server (if available)
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedSubsystemName )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[3] - Object Type Name
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedObjectTypeName )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedObjectTypeName );
+ ObjectTypeIndex = AuditParameters.ParameterCount;
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[4] - Object Name
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedObjectName )) {
+
+ SepSetParmTypeFileSpec( AuditParameters, AuditParameters.ParameterCount, CapturedObjectName );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[5] - New handle ID
+ //
+
+ if ( ARGUMENT_PRESENT( HandleId )) {
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, *HandleId );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ if ( ARGUMENT_PRESENT( OperationId )) {
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, (*OperationId).HighPart );
+
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, (*OperationId).LowPart );
+
+ AuditParameters.ParameterCount++;
+
+ } else {
+
+ AuditParameters.ParameterCount += 2;
+ }
+
+ //
+ // Parameter[6] - Subject's process id
+ //
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, ProcessID );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[7] - Subject's primary authentication ID
+ //
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, PrimaryAuthenticationId );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[8] - Subject's client authentication ID
+ //
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, ClientAuthenticationId );
+
+ } else {
+
+ SepSetParmTypeNoLogon( AuditParameters, AuditParameters.ParameterCount );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[9] - DesiredAccess mask
+ //
+
+ if ( AccessGranted ) {
+
+ SepSetParmTypeAccessMask( AuditParameters, AuditParameters.ParameterCount, GrantedAccess, ObjectTypeIndex );
+
+ } else {
+
+ SepSetParmTypeAccessMask( AuditParameters, AuditParameters.ParameterCount, DesiredAccess, ObjectTypeIndex );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[10] - Privileges used for open
+ //
+
+ if ( (CapturedPrivileges != NULL) && (CapturedPrivileges->PrivilegeCount > 0) ) {
+
+ SepSetParmTypePrivileges( AuditParameters, AuditParameters.ParameterCount, CapturedPrivileges );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ return( TRUE );
+}
+
+
+
+
+VOID
+SepAdtCloseObjectAuditAlarm (
+ IN PUNICODE_STRING CapturedSubsystemName,
+ IN PVOID HandleId,
+ IN PVOID Object,
+ IN PSID UserSid,
+ IN LUID AuthenticationId
+ )
+
+/*++
+
+Routine Description:
+
+ This routine implements NtCloseObjectAuditAlarm after parameters have
+ been captured.
+
+ This routine is used to generate audit and alarm messages when a handle
+ to a protected subsystem object is deleted. This routine may result in
+ several messages being generated and sent to Port objects. This may
+ result in a significant latency before returning. Design of routines
+ that must call this routine must take this potential latency into
+ account. This may have an impact on the approach taken for data
+ structure mutex locking, for example.
+
+ This API requires the caller have SeTcbPrivilege privilege. The test
+ for this privilege is always against the primary token of the calling
+ process, allowing the caller to be impersonating a client during the
+ call with no ill effects. It is assumed that this privilege has been
+ tested at a higher level.
+
+ This routine will create an SE_ADT_PARAMETERS array organized as follows:
+
+ Parameter[0] - User Sid
+
+ Parameter[1] - Subsystem name (if available)
+
+ Parameter[2] - New handle ID
+
+ Parameter[3] - Subject's process id
+
+Arguments:
+
+ CapturedSubsystemName - Supplies a name string identifying the
+ subsystem calling the routine.
+
+ HandleId - A unique value representing the client's handle to the
+ object.
+
+ Object - The address of the object being closed
+
+ UserSid - The Sid identifying the current caller.
+
+
+
+Return value:
+
+ None.
+
+
+--*/
+
+{
+
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ BOOLEAN AccessGranted = TRUE;
+ HANDLE ProcessId;
+
+ PAGED_CODE();
+
+ if ( SepAdtAuditThisEvent( AuditCategoryObjectAccess, &AccessGranted ) ) {
+
+ //
+ // A completely zero'd entry will be interpreted
+ // as a "null string" or not supplied parameter.
+ //
+ // Initializing the entire array up front will allow
+ // us to avoid filling in each not supplied entry.
+ //
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_OBJECT_ACCESS;
+ AuditParameters.AuditId = SE_AUDITID_CLOSE_HANDLE;
+ AuditParameters.ParameterCount = 0;
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+
+ //
+ // Parameter[0] - User Sid
+ //
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid );
+
+ AuditParameters.ParameterCount++;
+
+
+ //
+ // Parameter[1] - Subsystem name (if available)
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedSubsystemName )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[2] - Subsystem name (if available)
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedSubsystemName )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[3] - New handle ID
+ //
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, HandleId );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[4] - Subject's process id
+ //
+
+ ProcessId = PsProcessAuditId( PsGetCurrentProcess() );
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, ProcessId );
+
+ AuditParameters.ParameterCount++;
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ }
+}
+
+
+
+VOID
+SepAdtDeleteObjectAuditAlarm (
+ IN PUNICODE_STRING CapturedSubsystemName,
+ IN PVOID HandleId,
+ IN PVOID Object,
+ IN PSID UserSid,
+ IN LUID AuthenticationId
+ )
+
+/*++
+
+Routine Description:
+
+ This routine implements NtDeleteObjectAuditAlarm after parameters have
+ been captured.
+
+ This routine is used to generate audit and alarm messages when an object
+ in a protected subsystem object is deleted. This routine may result in
+ several messages being generated and sent to Port objects. This may
+ result in a significant latency before returning. Design of routines
+ that must call this routine must take this potential latency into
+ account. This may have an impact on the approach taken for data
+ structure mutex locking, for example.
+
+ This API requires the caller have SeTcbPrivilege privilege. The test
+ for this privilege is always against the primary token of the calling
+ process, allowing the caller to be impersonating a client during the
+ call with no ill effects. It is assumed that this privilege has been
+ tested at a higher level.
+
+ This routine will create an SE_ADT_PARAMETERS array organized as follows:
+
+ Parameter[0] - User Sid
+
+ Parameter[1] - Subsystem name (if available)
+
+ Parameter[2] - Handle ID
+
+ Parameter[3] - Subject's process id
+
+Arguments:
+
+ CapturedSubsystemName - Supplies a name string identifying the
+ subsystem calling the routine.
+
+ HandleId - A unique value representing the client's handle to the
+ object.
+
+ Object - The address of the object being closed
+
+ UserSid - The Sid identifying the current caller.
+
+
+
+Return value:
+
+ None.
+
+
+--*/
+
+{
+
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ BOOLEAN AccessGranted = TRUE;
+ HANDLE ProcessId;
+
+ PAGED_CODE();
+
+ if ( SepAdtAuditThisEvent( AuditCategoryObjectAccess, &AccessGranted ) ) {
+
+ //
+ // A completely zero'd entry will be interpreted
+ // as a "null string" or not supplied parameter.
+ //
+ // Initializing the entire array up front will allow
+ // us to avoid filling in each not supplied entry.
+ //
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_OBJECT_ACCESS;
+ AuditParameters.AuditId = SE_AUDITID_DELETE_OBJECT;
+ AuditParameters.ParameterCount = 0;
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+
+ //
+ // Parameter[0] - User Sid
+ //
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid );
+
+ AuditParameters.ParameterCount++;
+
+
+ //
+ // Parameter[1] - Subsystem name (if available)
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedSubsystemName )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[2] - Subsystem name (if available)
+ //
+
+ if ( ARGUMENT_PRESENT( CapturedSubsystemName )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CapturedSubsystemName );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[3] - New handle ID
+ //
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, HandleId );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[4] - Subject's process id
+ //
+
+ ProcessId = PsProcessAuditId( PsGetCurrentProcess() );
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, ProcessId );
+
+ AuditParameters.ParameterCount++;
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ }
+}
+
+
+
+//
+//VOID
+//SepAdtTraverseAuditAlarm(
+// IN PLUID OperationId,
+// IN PVOID DirectoryObject,
+// IN PSID UserSid,
+// IN LUID AuthenticationId,
+// IN ACCESS_MASK DesiredAccess,
+// IN PPRIVILEGE_SET Privileges OPTIONAL,
+// IN BOOLEAN AccessGranted,
+// IN BOOLEAN GenerateAudit,
+// IN BOOLEAN GenerateAlarm
+// )
+///*++
+//
+//Routine Description:
+//
+// This routine constructs an audit record to record that a request
+// to traverse a directory has occurred.
+//
+//Arguments:
+//
+// OperationID - LUID identifying the operation in progress
+//
+// DirectoryObject - Pointer to the directory being traversed.
+//
+// UserSid - Provides the User Sid for the caller.
+//
+// DesiredAccess - Mask to indicate the traverse access for this object
+// type.
+//
+// Privileges - Optional parameter to indicate any privilges that the
+// subject may have used to gain access to the object.
+//
+// AccessGranted - Indicates if the access was granted or denied based on
+// the access check or privilege check.
+//
+// GenerateAudit - Indicates if we should generate an audit for this operation.
+//
+// GenerateAlarm - Indicates if we should generate an alarm for this operation.
+//
+//Return Value:
+//
+// None.
+//
+//--*/
+//{
+// POLICY_AUDIT_TRAVERSE AuditTraverse;
+//
+// UNREFERENCED_PARAMETER( GenerateAudit );
+// UNREFERENCED_PARAMETER( GenerateAlarm );
+// UNREFERENCED_PARAMETER( DirectoryObject );
+// UNREFERENCED_PARAMETER( DesiredAccess );
+//
+// //
+// // BUGWARNING need a way to get the directory name from
+// // the directory object
+// //
+//
+// AuditTraverse.AccessGranted = AccessGranted;
+// AuditTraverse.DirectoryName = NULL;
+// AuditTraverse.OperationId = *OperationId;
+// AuditTraverse.PrivilegeSet = Privileges;
+// AuditTraverse.UserSid = UserSid;
+// AuditTraverse.AuthenticationId = AuthenticationId;
+//
+//// SepAdtLogAuditRecord( AuditEventTraverse, &AuditTraverse );
+//}
+
+
+
+
+//
+//VOID
+//SepAdtCreateObjectAuditAlarm(
+// IN PLUID OperationID,
+// IN PUNICODE_STRING DirectoryName,
+// IN PUNICODE_STRING ComponentName,
+// IN PSID UserSid,
+// IN LUID AuthenticationId,
+// IN ACCESS_MASK DesiredAccess,
+// IN BOOLEAN AccessGranted,
+// IN BOOLEAN GenerateAudit,
+// IN BOOLEAN GenerateAlarm
+// )
+///*++
+//
+//Routine Description:
+//
+// description-of-function.
+//
+//Arguments:
+//
+//
+// GenerateAudit - Indicates if we should generate an audit for this operation.
+//
+// GenerateAlarm - Indicates if we should generate an alarm for this operation.
+//
+//Return Value:
+//
+// return-value - Description of conditions needed to return value. - or -
+// None.
+//
+//--*/
+//
+//{
+// POLICY_AUDIT_CREATE_OBJECT AuditCreateObject;
+//
+// UNREFERENCED_PARAMETER( GenerateAudit );
+// UNREFERENCED_PARAMETER( GenerateAlarm );
+//
+//
+// AuditCreateObject.AccessGranted = AccessGranted;
+// AuditCreateObject.DesiredAccess = DesiredAccess;
+// AuditCreateObject.DirectoryName = DirectoryName;
+// AuditCreateObject.ComponentName = ComponentName;
+// AuditCreateObject.OperationId = *OperationID;
+// AuditCreateObject.UserSid = UserSid;
+// AuditCreateObject.AuthenticationId = AuthenticationId;
+//
+//// SepAdtLogAuditRecord( AuditEventCreateObject, &AuditCreateObject );
+//}
+
+
+
+//
+//VOID
+//SepAdtImplicitObjectAuditAlarm(
+// IN PLUID OperationId OPTIONAL,
+// IN PVOID Object,
+// IN PSID UserSid,
+// IN ACCESS_MASK DesiredAccess,
+// IN PPRIVILEGE_SET Privileges OPTIONAL,
+// IN BOOLEAN AccessGranted,
+// IN BOOLEAN GenerateAudit,
+// IN BOOLEAN GenerateAlarm
+// )
+///*++
+//
+//Routine Description:
+//
+// description-of-function.
+//
+//Arguments:
+//
+// GenerateAudit - Indicates if we should generate an audit for this operation.
+//
+// GenerateAlarm - Indicates if we should generate an alarm for this operation.
+//
+//
+//Return Value:
+//
+// None
+//
+//--*/
+//
+//{
+// POLICY_AUDIT_IMPLICIT_ACCESS AuditImplicitAccess;
+//
+// UNREFERENCED_PARAMETER( GenerateAudit );
+// UNREFERENCED_PARAMETER( GenerateAlarm );
+//
+//
+// //
+// // BUGWARNING need a way to obtain the object type
+// //
+//
+// AuditImplicitAccess.AccessGranted = AccessGranted;
+// AuditImplicitAccess.DesiredAccess = DesiredAccess;
+// AuditImplicitAccess.ObjectTypeName = NULL;
+// AuditImplicitAccess.OperationId = *OperationId;
+// AuditImplicitAccess.PrivilegeSet = Privileges;
+// AuditImplicitAccess.UserSid = UserSid;
+//
+// SepAdtLogAuditRecord( AuditEventImplicitAccess, &AuditImplicitAccess );
+//}
+
+
+
+
+
+VOID
+SepAdtHandleAuditAlarm(
+ IN PUNICODE_STRING Source,
+ IN LUID OperationId,
+ IN HANDLE Handle,
+ IN PSID UserSid
+ )
+
+/*++
+
+Routine Description:
+
+ Creates an audit record for the creation of an object handle.
+
+Arguments:
+
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ BOOLEAN AccessGranted = TRUE;
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ HANDLE ProcessID;
+
+ PAGED_CODE();
+
+ if ( SepAdtAuditThisEvent( AuditCategoryObjectAccess, &AccessGranted )) {
+
+ //
+ // A completely zero'd entry will be interpreted
+ // as a "null string" or not supplied parameter.
+ //
+ // Initializing the entire array up front will allow
+ // us to avoid filling in each not supplied entry.
+ //
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_OBJECT_ACCESS;
+ AuditParameters.AuditId = SE_AUDITID_CREATE_HANDLE;
+ AuditParameters.ParameterCount = 0;
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+
+ //
+ // Parameter[0] - User Sid
+ //
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid );
+
+ AuditParameters.ParameterCount++;
+
+
+ //
+ // Parameter[1] - Subsystem name (if available)
+ //
+
+ if ( ARGUMENT_PRESENT( Source )) {
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, Source );
+ }
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameter[2] - New handle ID
+ //
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, Handle );
+
+ AuditParameters.ParameterCount++;
+
+ //
+ // Parameters 3,4 - Operation ID
+ //
+
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, OperationId.HighPart );
+
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, OperationId.LowPart );
+
+ AuditParameters.ParameterCount++;
+
+
+ //
+ // Parameter[5] - Subject's process id
+ //
+
+ ProcessID = PsProcessAuditId( PsGetCurrentProcess() );
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, ProcessID );
+
+ AuditParameters.ParameterCount++;
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ }
+}
+
+
+
+
+VOID
+SepAdtObjectReferenceAuditAlarm(
+ IN PLUID OperationId OPTIONAL,
+ IN PVOID Object,
+ IN PSECURITY_SUBJECT_CONTEXT SubjectSecurityContext,
+ IN ACCESS_MASK DesiredAccess,
+ IN PPRIVILEGE_SET Privileges OPTIONAL,
+ IN BOOLEAN AccessGranted,
+ IN BOOLEAN GenerateAudit,
+ IN BOOLEAN GenerateAlarm
+ )
+
+/*++
+
+Routine Description:
+
+ description-of-function.
+
+ This routine will create an SE_ADT_PARAMETERS array organized as follows:
+
+ Parameter[0] - User Sid
+
+ Parameter[1] - Subsystem name (if available)
+
+ Parameter[2] - Object Type Name
+
+ Parameter[3] - Object Name
+
+ Parameter[4] - Subject's process id
+
+ Parameter[5] - Subject's primary authentication ID
+
+ Parameter[6] - Subject's client authentication ID
+
+ Parameter[7] - DesiredAccess mask
+
+
+Arguments:
+
+ GenerateAudit - Indicates if we should generate an audit for this operation.
+
+ GenerateAlarm - Indicates if we should generate an alarm for this operation.
+
+Return Value:
+
+ return-value - Description of conditions needed to return value. - or -
+ None.
+
+--*/
+
+{
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ ULONG ObjectTypeIndex;
+ POBJECT_NAME_INFORMATION ObjectNameInformation;
+ PUNICODE_STRING ObjectTypeInformation;
+ PSID UserSid;
+ LUID PrimaryAuthenticationId;
+ LUID ClientAuthenticationId;
+
+ PTOKEN ClientToken = (PTOKEN)SubjectSecurityContext->ClientToken;
+ PTOKEN PrimaryToken = (PTOKEN)SubjectSecurityContext->PrimaryToken;
+
+ PAGED_CODE();
+
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ UserSid = SepTokenUserSid( ClientToken );
+ ClientAuthenticationId = SepTokenAuthenticationId( ClientToken );
+
+ } else {
+
+ UserSid = SepTokenUserSid( PrimaryToken );
+ }
+
+ PrimaryAuthenticationId = SepTokenAuthenticationId( PrimaryToken );
+
+ //
+ // A completely zero'd entry will be interpreted
+ // as a "null string" or not supplied parameter.
+ //
+ // Initializing the entire array up front will allow
+ // us to avoid filling in each not supplied entry.
+ //
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_DETAILED_TRACKING;
+ AuditParameters.AuditId = SE_AUDITID_INDIRECT_REFERENCE;
+ AuditParameters.ParameterCount = 8;
+
+ if ( AccessGranted ) {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+ } else {
+
+ AuditParameters.Type = EVENTLOG_AUDIT_FAILURE;
+ }
+
+ //
+ // Obtain the object name and object type name from the
+ // object.
+ //
+
+ ObjectNameInformation = SepQueryNameString( Object );
+
+
+ ObjectTypeInformation = SepQueryTypeString( Object );
+
+
+
+
+ //
+ // Parameter[0] - User Sid
+ //
+
+ SepSetParmTypeSid( AuditParameters, 0, UserSid );
+
+
+ //
+ // Parameter[1] - Subsystem name (if available)
+ //
+
+ SepSetParmTypeString( AuditParameters, 1, &SeSubsystemName );
+
+
+ //
+ // Parameter[2] - Object Type Name
+ //
+
+ if ( ObjectTypeInformation != NULL ) {
+
+ SepSetParmTypeString( AuditParameters, 2, ObjectTypeInformation );
+ ObjectTypeIndex = 2;
+ }
+
+
+
+ //
+ // Parameter[3] - Object Name
+ //
+
+ if ( ObjectNameInformation != NULL ) {
+
+ SepSetParmTypeString( AuditParameters, 3, &ObjectNameInformation->Name );
+ }
+
+
+
+
+ //
+ // Parameter[4] - Subject's process id
+ //
+
+ //
+ // BUGWARNING: The process Id is currently unavailable.
+ //
+
+ SepSetParmTypeUlong( AuditParameters, 4, SubjectSecurityContext->ProcessAuditId );
+
+
+
+
+ //
+ // Parameter[5] - Subject's primary authentication ID
+ //
+
+
+ SepSetParmTypeLogonId( AuditParameters, 5, PrimaryAuthenticationId );
+
+
+
+
+ //
+ // Parameter[6] - Subject's client authentication ID
+ //
+
+ if ( ARGUMENT_PRESENT( ClientToken )) {
+
+ SepSetParmTypeLogonId( AuditParameters, 6, ClientAuthenticationId );
+
+ } else {
+
+ SepSetParmTypeNoLogon( AuditParameters, 6 );
+
+ }
+
+ //
+ // Parameter[7] - DesiredAccess mask
+ //
+
+
+ SepSetParmTypeAccessMask( AuditParameters, 7, DesiredAccess, ObjectTypeIndex );
+
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ if ( ObjectNameInformation != NULL ) {
+ ExFreePool( ObjectNameInformation );
+ }
+
+ if ( ObjectTypeInformation != NULL ) {
+ ExFreePool( ObjectTypeInformation );
+ }
+
+}
+
+
+//VOID
+//SepAdtCreateInstanceAuditAlarm(
+// IN PLUID OperationID,
+// IN PVOID Object,
+// IN PSID UserSid,
+// IN LUID AuthenticationId,
+// IN ACCESS_MASK DesiredAccess,
+// IN PPRIVILEGE_SET Privileges OPTIONAL,
+// IN BOOLEAN AccessGranted,
+// IN BOOLEAN GenerateAudit,
+// IN BOOLEAN GenerateAlarm
+// )
+//
+///*++
+//
+//Routine Description:
+//
+// description-of-function.
+//
+//Arguments:
+//
+// GenerateAudit - Indicates if we should generate an audit for this operation.
+//
+// GenerateAlarm - Indicates if we should generate an alarm for this operation.
+//
+//
+//Return Value:
+//
+// return-value - Description of conditions needed to return value. - or -
+// None.
+//
+//--*/
+//
+//{
+// POLICY_AUDIT_CREATE_INSTANCE AuditCreateInstance;
+//
+// UNREFERENCED_PARAMETER( GenerateAudit );
+// UNREFERENCED_PARAMETER( GenerateAlarm );
+//
+// //
+// // BUGWARNING Must obtain the object type object from the passed
+// // object
+// //
+//
+// AuditCreateInstance.AccessGranted = AccessGranted;
+// AuditCreateInstance.ObjectTypeName = NULL;
+// AuditCreateInstance.OperationId = *OperationID;
+// AuditCreateInstance.UserSid = UserSid;
+// AuditCreateInstance.AuthenticationId = AuthenticationId;
+//
+//// SepAdtLogAuditRecord( AuditEventCreateInstance, &AuditCreateInstance );
+//
+// return;
+//}
+
+
+
+//
+//VOID
+//SeShutdownAuditAlarm(
+// VOID
+// )
+//
+///*++
+//
+//Routine Description:
+//
+// This routine will can a shutdown audit record to be generated.
+//
+// There must be a forced delay after this routine is called to ensure
+// that the generated audit record actually makes it to disk.
+//
+//Arguments:
+//
+// None
+//
+//Return Value:
+//
+// None.
+//
+//--*/
+//
+//{
+// SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
+// SE_ADT_PARAMETER_ARRAY AuditParameters;
+// UNICODE_STRING SubsystemName;
+// PSID UserSid;
+//
+// //
+// // Make sure we're auditing shutdown events.
+// //
+//
+// if ( SepAdtAuditThisEvent( AuditEventShutdown, NULL )) {
+//
+// SeCaptureSubjectContext( &SubjectSecurityContext );
+//
+//
+// //
+// // A completely zero'd entry will be interpreted
+// // as a "null string" or not supplied parameter.
+// //
+// // Initializing the entire array up front will allow
+// // us to avoid filling in each not supplied entry.
+// //
+//
+// RtlZeroMemory (
+// (PVOID) &AuditParameters,
+// sizeof( AuditParameters )
+// );
+//
+// ASSERT( SeAdtParmTypeNone == 0 );
+//
+// AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
+// AuditParameters.AuditId = SE_AUDITID_SYSTEM_SHUTDOWN;
+// AuditParameters.ParameterCount = 2;
+//
+// UserSid = SepTokenUserSid(EffectiveToken( &SubjectSecurityContext ));
+//
+//
+// RtlInitUnicodeString( &SubsystemName, L"Security" );
+//
+//
+// //
+// // Parameter[0] - User Sid
+// //
+//
+// SepSetParmTypeSid( AuditParameters, 0, UserSid );
+//
+//
+// //
+// // Parameter[1] - Subsystem name (if available)
+// //
+//
+// SepSetParmTypeString( AuditParameters, 1, &SubsystemName );
+//
+//
+// SepAdtLogAuditRecord( &AuditParameters );
+//
+// SeReleaseSubjectContext( &SubjectSecurityContext );
+//
+// }
+//
+//}
+
+
+
+
+
+//
+// BOOLEAN
+// SepAdtAuditThisEvent(
+// IN POLICY_AUDIT_EVENT_TYPE AuditType,
+// IN PBOOLEAN AccessGranted OPTIONAL
+// )
+//
+// /*++
+//
+// Routine Description:
+//
+// This routine will return whether or not to generate an audit log
+// record for the passed event type.
+//
+// Arguments:
+//
+// AuditType - The type of event to be audited.
+//
+// AccessGranted - An optional flag indicating whether or not
+// the operation was successful. This does not all apply to all
+// types of audit events.
+//
+// Note that a pointer to the flag is passed rather than the
+// flag itself, so that we may tell whether or not the argument
+// is present.
+//
+// Return Value:
+//
+// Flag indicating whether or not to proceed with the audit.
+//
+// --*/
+//
+// {
+// PAGED_CODE();
+//
+// if (SepAdtAuditingEnabled) {
+//
+// if ( ARGUMENT_PRESENT( AccessGranted )) {
+//
+// if ((SeAuditingState[AuditType].AuditOnSuccess && *AccessGranted) ||
+// SeAuditingState[AuditType].AuditOnFailure && !(*AccessGranted)) {
+//
+// return( TRUE );
+//
+// }
+// }
+// }
+//
+// return( FALSE );
+// }
+
+
+
+
+
+POBJECT_NAME_INFORMATION
+SepQueryNameString(
+ IN PVOID Object
+ )
+
+/*++
+
+Routine Description:
+
+ Takes a pointer to an object and returns the name of the object.
+
+Arguments:
+
+ Object - a pointer to an object.
+
+
+Return Value:
+
+ A pointer to a buffer containing a POBJECT_NAME_INFORMATION
+ structure containing the name of the object. The string is
+ allocated out of paged pool and should be freed by the caller.
+
+ NULL may also be returned.
+
+
+--*/
+
+{
+ NTSTATUS Status;
+ ULONG ReturnLength = 0;
+ POBJECT_NAME_INFORMATION ObjectNameInfo = NULL;
+ PUNICODE_STRING ObjectName = NULL;
+
+ PAGED_CODE();
+
+ Status = ObQueryNameString(
+ Object,
+ ObjectNameInfo,
+ 0,
+ &ReturnLength
+ );
+
+ if ( Status == STATUS_INFO_LENGTH_MISMATCH ) {
+
+ ObjectNameInfo = ExAllocatePoolWithTag( PagedPool, ReturnLength, 'nOeS' );
+
+ if ( ObjectNameInfo != NULL ) {
+
+ Status = ObQueryNameString(
+ Object,
+ ObjectNameInfo,
+ ReturnLength,
+ &ReturnLength
+ );
+
+ if ( NT_SUCCESS( Status )) {
+
+ if (ObjectNameInfo->Name.Length != 0) {
+
+ return( ObjectNameInfo );
+
+ } else {
+
+ ExFreePool( ObjectNameInfo );
+ return( NULL );
+ }
+ }
+ }
+ }
+
+ return( NULL );
+}
+
+
+
+
+PUNICODE_STRING
+SepQueryTypeString(
+ IN PVOID Object
+ )
+/*++
+
+Routine Description:
+
+ Takes a pointer to an object and returns the type of the object.
+
+Arguments:
+
+ Object - a pointer to an object.
+
+
+Return Value:
+
+ A pointer to a UNICODE_STRING that contains the name of the object
+ type. The string is allocated out of paged pool and should be freed
+ by the caller.
+
+ NULL may also be returned.
+
+
+--*/
+
+{
+
+ NTSTATUS Status;
+ PUNICODE_STRING TypeName = NULL;
+ ULONG ReturnLength;
+
+ PAGED_CODE();
+
+ Status = ObQueryTypeName(
+ Object,
+ TypeName,
+ 0,
+ &ReturnLength
+ );
+
+ if ( Status == STATUS_INFO_LENGTH_MISMATCH ) {
+
+ TypeName = ExAllocatePoolWithTag( PagedPool, ReturnLength, 'nTeS' );
+
+ if ( TypeName != NULL ) {
+
+ Status = ObQueryTypeName(
+ Object,
+ TypeName,
+ ReturnLength,
+ &ReturnLength
+ );
+
+ if ( NT_SUCCESS( Status )) {
+
+ return( TypeName );
+ }
+ }
+ }
+
+ return( NULL );
+}
+
+
+
+VOID
+SeAuditProcessCreation(
+ PEPROCESS Process,
+ PEPROCESS Parent
+ )
+/*++
+
+Routine Description:
+
+ Audits the creation of a process. It is the caller's responsibility
+ to determine if process auditing is in progress.
+
+
+Arguments:
+
+ Process - Points to the new process object.
+
+ Parent - Points to the creator (parent) process object.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ ANSI_STRING Ansi;
+ LUID UserAuthenticationId;
+ NTSTATUS Status;
+ PSID UserSid;
+ SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ UNICODE_STRING ImageFileName;
+
+ PAGED_CODE();
+
+ RtlInitAnsiString( &Ansi, Process->ImageFileName );
+
+ Status = RtlAnsiStringToUnicodeString(
+ &ImageFileName,
+ &Ansi,
+ TRUE
+ );
+
+ //
+ // Not enough memory to complete the audit, return.
+ //
+
+ if ( !NT_SUCCESS( Status )) {
+ return;
+ }
+
+ SeCaptureSubjectContext( &SubjectSecurityContext );
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_DETAILED_TRACKING;
+ AuditParameters.AuditId = SE_AUDITID_PROCESS_CREATED;
+ AuditParameters.ParameterCount = 0;
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+ //
+ // Use the primary token here, because that's what's going to show up
+ // when the created process exits.
+ //
+
+ UserSid = SepTokenUserSid( SubjectSecurityContext.PrimaryToken );
+
+ UserAuthenticationId = SepTokenAuthenticationId( SubjectSecurityContext.PrimaryToken );
+
+ //
+ // Fill in the AuditParameters structure.
+ //
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &SeSubsystemName );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, Process );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &ImageFileName );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, Parent );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, UserAuthenticationId );
+ AuditParameters.ParameterCount++;
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ SeReleaseSubjectContext( &SubjectSecurityContext );
+
+ RtlFreeUnicodeString( &ImageFileName );
+
+ return;
+}
+
+
+VOID
+SeAuditHandleDuplication(
+ PVOID SourceHandle,
+ PVOID NewHandle,
+ PEPROCESS SourceProcess,
+ PEPROCESS TargetProcess
+ )
+
+/*++
+
+Routine Description:
+
+ This routine generates a handle duplication audit. It is up to the caller
+ to determine if this routine should be called or not.
+
+Arguments:
+
+ SourceHandle - Original handle
+
+ NewHandle - New handle
+
+ SourceProcess - Process containing SourceHandle
+
+ TargetProcess - Process containing NewHandle
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ SECURITY_SUBJECT_CONTEXT SubjectSecurityContext;
+ PSID UserSid;
+
+ PAGED_CODE();
+
+ SeCaptureSubjectContext( &SubjectSecurityContext );
+
+ UserSid = SepTokenUserSid( EffectiveToken( &SubjectSecurityContext ));
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_DETAILED_TRACKING;
+ AuditParameters.AuditId = SE_AUDITID_DUPLICATE_HANDLE;
+ AuditParameters.ParameterCount = 0;
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &SeSubsystemName );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, SourceHandle );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, PsProcessAuditId( SourceProcess ));
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, NewHandle );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, PsProcessAuditId( TargetProcess ));
+ AuditParameters.ParameterCount++;
+
+
+ SepAdtLogAuditRecord( &AuditParameters );
+
+ SeReleaseSubjectContext( &SubjectSecurityContext );
+}
+
+
+VOID
+SeAuditProcessExit(
+ PEPROCESS Process
+ )
+/*++
+
+Routine Description:
+
+ Audits the exit of a process. The caller is responsible for
+ determining if this should be called.
+
+Arguments:
+
+ Process - Pointer to the process object that is exiting.
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+ PTOKEN Token;
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ PSID UserSid;
+ LUID LogonId;
+
+ PAGED_CODE();
+
+ Token = (PTOKEN)Process->Token;
+
+ UserSid = SepTokenUserSid( Token );
+ LogonId = SepTokenAuthenticationId( Token );
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_DETAILED_TRACKING;
+ AuditParameters.AuditId = SE_AUDITID_PROCESS_EXIT;
+ AuditParameters.ParameterCount = 0;
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &SeSubsystemName );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, PsProcessAuditId( Process ));
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, LogonId );
+ AuditParameters.ParameterCount++;
+
+ SepAdtLogAuditRecord( &AuditParameters );
+}
+
+
+
+VOID
+SepAdtGenerateDiscardAudit(
+ VOID
+ )
+
+/*++
+
+Routine Description:
+
+ Generates an 'audits discarded' audit.
+
+Arguments:
+
+ none
+
+Return Value:
+
+ None.
+
+--*/
+
+{
+
+ SE_ADT_PARAMETER_ARRAY AuditParameters;
+ PSID UserSid;
+
+ PAGED_CODE();
+
+ UserSid = SeLocalSystemSid;
+
+ RtlZeroMemory (
+ (PVOID) &AuditParameters,
+ sizeof( AuditParameters )
+ );
+
+
+ ASSERT( SeAdtParmTypeNone == 0 );
+
+ AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
+ AuditParameters.AuditId = SE_AUDITID_AUDITS_DISCARDED;
+ AuditParameters.ParameterCount = 0;
+ AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
+
+ SepSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &SeSubsystemName );
+ AuditParameters.ParameterCount++;
+
+ SepSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, SepAdtCountEventsDiscarded );
+ AuditParameters.ParameterCount++;
+
+ SepAdtLogAuditRecord( &AuditParameters );
+}