2630 lines
67 KiB
C
2630 lines
67 KiB
C
/*++
|
||
|
||
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 );
|
||
}
|