3293 lines
80 KiB
C
3293 lines
80 KiB
C
/*++
|
||
|
||
Copyright (c) 1991 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
adtevent.c
|
||
|
||
Abstract:
|
||
|
||
Functions that implement audits generated by LSA itself.
|
||
|
||
Author:
|
||
|
||
Scott Birrell (ScottBi) January 19, 1993
|
||
|
||
Environment:
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
#include <lsapch2.h>
|
||
#include "adtp.h"
|
||
#include "adtutil.h"
|
||
|
||
|
||
|
||
// ----------------------------------------------------------------------
|
||
|
||
|
||
//
|
||
// Lsa Global flags to indicate if we are auditing logon events.
|
||
//
|
||
|
||
BOOLEAN LsapAuditSuccessfulLogons = FALSE;
|
||
BOOLEAN LsapAuditFailedLogons = FALSE;
|
||
|
||
|
||
//
|
||
// Forwards
|
||
//
|
||
NTSTATUS
|
||
LsapAdtGetDbAttributesChangeString(
|
||
IN LSAP_DB_ATTRIBUTE* OldAttributes,
|
||
IN LSAP_DB_ATTRIBUTE* NewAttributes,
|
||
IN ULONG AttributeCount,
|
||
OUT LPWSTR* AttributeChangeString
|
||
);
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtGenerateObjectOperationAuditEvent(
|
||
IN LSAPR_HANDLE ObjectHandle,
|
||
IN USHORT AuditEventType,
|
||
IN OBJECT_OPERATION_TYPE OperationType
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generates an audit entry when an operation on the object
|
||
represented by ObjectHandle succeds/fails and if this type of
|
||
auditing is enabled.
|
||
|
||
Arguments:
|
||
|
||
ObjectHandle - Handle of the object being accessed
|
||
|
||
AuditEventType - The type of audit event to be generated.
|
||
EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
|
||
|
||
OperationType - Type of operation performed on the object
|
||
represented by ObjectHandle.
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
LUID ClientAuthenticationId;
|
||
PTOKEN_USER TokenUserInformation=NULL;
|
||
UNICODE_STRING OperationTypeName;
|
||
LSAP_DB_HANDLE InternalHandle;
|
||
UNICODE_STRING ObjectName;
|
||
LUID SystemAuthId = SYSTEM_LUID;
|
||
|
||
static LPCWSTR ObjectOperationNames[ObjectOperationDummyLast] = {
|
||
L"None",
|
||
L"Query"
|
||
};
|
||
|
||
LsapEnterFunc("LsapAdtGenerateObjectAcessAuditEvent");
|
||
|
||
if (!LsapAdtIsAuditingEnabledForCategory( AuditCategoryObjectAccess,
|
||
AuditEventType)) {
|
||
goto FunctionReturn;
|
||
}
|
||
|
||
InternalHandle = (LSAP_DB_HANDLE) ObjectHandle;
|
||
|
||
Status = LsapQueryClientInfo(
|
||
&TokenUserInformation,
|
||
&ClientAuthenticationId
|
||
);
|
||
|
||
if ( !NT_SUCCESS( Status )) {
|
||
goto Cleanup;
|
||
}
|
||
|
||
if ( RtlEqualLuid( &ClientAuthenticationId, &SystemAuthId )) {
|
||
|
||
//
|
||
// do not audit secret queries by the system
|
||
//
|
||
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// LsarQuerySecret sometimes passes us a secret whose name will
|
||
// be rejected by ElfReportEventW because the length parameter
|
||
// includes the terminating NULL.
|
||
//
|
||
// For example,
|
||
// name.Buffer = "foo\0"
|
||
// name.Length = 8
|
||
// name.MaximumLength = 8
|
||
//
|
||
// We cannot change the input param or change the LSA code to
|
||
// not do this, therfore we make a local copy, fix it
|
||
// and use that instead
|
||
//
|
||
|
||
ObjectName = InternalHandle->PhysicalNameU;
|
||
ObjectName.Length = (USHORT) LsapSafeWcslen( ObjectName.Buffer,
|
||
ObjectName.MaximumLength );
|
||
|
||
//
|
||
// Build an audit parameters structure.
|
||
//
|
||
RtlInitUnicodeString( &OperationTypeName, ObjectOperationNames[OperationType] );
|
||
|
||
LsapAdtInitParametersArray(
|
||
&AuditParameters,
|
||
SE_CATEGID_OBJECT_ACCESS,
|
||
SE_AUDITID_OBJECT_OPERATION,
|
||
AuditEventType,
|
||
11, // there are 11 params to init
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
SeAdtParmTypeSid, TokenUserInformation->User.Sid,
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
SeAdtParmTypeString, &LsapSubsystemName,
|
||
|
||
//
|
||
// Operation Type
|
||
//
|
||
SeAdtParmTypeString, &OperationTypeName,
|
||
|
||
//
|
||
// Object Type : index of this is 3, used later
|
||
//
|
||
SeAdtParmTypeString, &LsapDbObjectTypeNames[InternalHandle->
|
||
ObjectTypeId],
|
||
|
||
//
|
||
// Object Name
|
||
//
|
||
SeAdtParmTypeString, &ObjectName,
|
||
|
||
//
|
||
// Object Handle ID
|
||
//
|
||
SeAdtParmTypePtr, ObjectHandle,
|
||
|
||
//
|
||
// Primary Authentication information
|
||
//
|
||
SeAdtParmTypeLogonId, LsapSystemLogonId,
|
||
|
||
//
|
||
// Clients's Authentication information
|
||
//
|
||
SeAdtParmTypeLogonId, ClientAuthenticationId,
|
||
|
||
//
|
||
// Requested access : 3 is the index of ObjectType parameter
|
||
//
|
||
SeAdtParmTypeAccessMask, InternalHandle->RequestedAccess, 3,
|
||
|
||
//
|
||
// there are no object properties (object-type list)
|
||
//
|
||
SeAdtParmTypeNone,
|
||
|
||
//
|
||
// no additional information
|
||
//
|
||
SeAdtParmTypeNone
|
||
|
||
);
|
||
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Cleanup:
|
||
|
||
if (TokenUserInformation != NULL)
|
||
{
|
||
LsapFreeLsaHeap( TokenUserInformation );
|
||
}
|
||
|
||
if (!NT_SUCCESS(Status)) {
|
||
|
||
LsapAuditFailed( Status );
|
||
}
|
||
|
||
FunctionReturn:
|
||
LsapExitFunc("LsapAdtGenerateObjectAcessAuditEvent", Status);
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtGenerateLsaAuditEvent(
|
||
IN LSAPR_HANDLE ObjectHandle,
|
||
IN ULONG AuditEventCategory,
|
||
IN ULONG AuditEventId,
|
||
IN PPRIVILEGE_SET Privileges,
|
||
IN ULONG SidCount,
|
||
IN PSID *Sids OPTIONAL,
|
||
IN ULONG UnicodeStringCount,
|
||
IN PUNICODE_STRING UnicodeStrings OPTIONAL,
|
||
IN PLSARM_POLICY_AUDIT_EVENTS_INFO PolicyAuditEventsInfo OPTIONAL
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function generates an Lsa-originated Audit Event. Audit Events
|
||
of this kind are generated as a result of Local Security Policy changes
|
||
such as assigning/removing user rights to an account.
|
||
|
||
Arguments:
|
||
|
||
ObjectHandle - Specifies the handle of an object in the Lsa Policy
|
||
Database. For global changes to policy, a handle to the
|
||
Lsa Policy object is passed.
|
||
|
||
AuditEventCategory - Specifies the Id of the Audit Event Category
|
||
to which this Audit Event belongs.
|
||
|
||
AuditEventId - Specifies the Id of the Audit Event being generated.
|
||
|
||
LuidCount - Count of Locally Unique Ids being passed via the Luids
|
||
parameter. If no Locally Unique Ids are passed, this parameter must
|
||
be set to 0.
|
||
|
||
Luids - Pointer to array of LuidCount Locally Unique Ids and their attributes.
|
||
The attributes are ignored. If 0 is passed for the LuidCount
|
||
parameter, this parameter is ignored and NULL may be specified.
|
||
|
||
SidCount - Count of Sids being passed via the Sids parameter. If no
|
||
Sids are passed, this parameter must be set to 0.
|
||
|
||
Sids - Pointer to array of SidCount Sids. If 0 is passed for the
|
||
SidCount parameter, this parameter is ignored and NULL may be
|
||
specified.
|
||
|
||
UnicodeStringCount - Count of Unicode Strings being passed via the
|
||
UnicodeStrings parameter. If no Unicode Strings are passed, this
|
||
parameter must be set to 0.
|
||
|
||
UnicodeStrings - Pointer to array of UnicodeStringCount strings. If 0 is
|
||
passed for the SidCount parameter, this parameter is ignored and NULL
|
||
may be specified.
|
||
|
||
PolicyAuditEventsInfo - Pointer to Auditing Events information structure
|
||
containing the AuditingMode and the array of Policy Audit Event
|
||
Information entries. This parameter must be non-NULL if and only if
|
||
the AuditEventCategory parameter is SE_AUDIT_POLICY_CHANGE.
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
LUID ClientAuthenticationId;
|
||
PTOKEN_USER TokenUserInformation = NULL;
|
||
PSID ClientSid;
|
||
|
||
|
||
UNREFERENCED_PARAMETER( ObjectHandle );
|
||
|
||
Status = LsapQueryClientInfo(
|
||
&TokenUserInformation,
|
||
&ClientAuthenticationId
|
||
);
|
||
|
||
if ( !NT_SUCCESS( Status )) {
|
||
|
||
goto Cleanup;
|
||
}
|
||
|
||
ClientSid = TokenUserInformation->User.Sid;
|
||
|
||
Status = LsapAdtGenerateLsaAuditEventWithClientSid( AuditEventCategory,
|
||
AuditEventId,
|
||
ClientSid,
|
||
ClientAuthenticationId,
|
||
Privileges,
|
||
SidCount,
|
||
Sids,
|
||
UnicodeStringCount,
|
||
UnicodeStrings,
|
||
PolicyAuditEventsInfo );
|
||
|
||
|
||
|
||
Cleanup:
|
||
|
||
if (TokenUserInformation != NULL)
|
||
{
|
||
LsapFreeLsaHeap( TokenUserInformation );
|
||
}
|
||
|
||
if ( !NT_SUCCESS( Status )) {
|
||
|
||
LsapAuditFailed( Status );
|
||
}
|
||
|
||
return(Status);
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtGenerateLsaAuditEventWithClientSid(
|
||
IN ULONG AuditEventCategory,
|
||
IN ULONG AuditEventId,
|
||
IN PSID ClientSid,
|
||
IN LUID ClientAuthenticationId,
|
||
IN PPRIVILEGE_SET Privileges,
|
||
IN ULONG SidCount,
|
||
IN PSID *Sids OPTIONAL,
|
||
IN ULONG UnicodeStringCount,
|
||
IN PUNICODE_STRING UnicodeStrings OPTIONAL,
|
||
IN PLSARM_POLICY_AUDIT_EVENTS_INFO PolicyAuditEventsInfo OPTIONAL
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function generates an Lsa-originated Audit Event. Audit Events
|
||
of this kind are generated as a result of Local Security Policy changes
|
||
such as assigning/removing user rights to an account.
|
||
|
||
Arguments:
|
||
|
||
ObjectHandle - Specifies the handle of an object in the Lsa Policy
|
||
Database. For global changes to policy, a handle to the
|
||
Lsa Policy object is passed.
|
||
|
||
AuditEventCategory - Specifies the Id of the Audit Event Category
|
||
to which this Audit Event belongs.
|
||
|
||
AuditEventId - Specifies the Id of the Audit Event being generated.
|
||
|
||
LuidCount - Count of Locally Unique Ids being passed via the Luids
|
||
parameter. If no Locally Unique Ids are passed, this parameter must
|
||
be set to 0.
|
||
|
||
Luids - Pointer to array of LuidCount Locally Unique Ids and their attributes.
|
||
The attributes are ignored. If 0 is passed for the LuidCount
|
||
parameter, this parameter is ignored and NULL may be specified.
|
||
|
||
SidCount - Count of Sids being passed via the Sids parameter. If no
|
||
Sids are passed, this parameter must be set to 0.
|
||
|
||
Sids - Pointer to array of SidCount Sids. If 0 is passed for the
|
||
SidCount parameter, this parameter is ignored and NULL may be
|
||
specified.
|
||
|
||
UnicodeStringCount - Count of Unicode Strings being passed via the
|
||
UnicodeStrings parameter. If no Unicode Strings are passed, this
|
||
parameter must be set to 0.
|
||
|
||
UnicodeStrings - Pointer to array of UnicodeStringCount strings. If 0 is
|
||
passed for the SidCount parameter, this parameter is ignored and NULL
|
||
may be specified.
|
||
|
||
PolicyAuditEventsInfo - Pointer to Auditing Events information structure
|
||
containing the AuditingMode and the array of Policy Audit Event
|
||
Information entries. This parameter must be non-NULL if and only if
|
||
the AuditEventCategory parameter is SE_AUDIT_POLICY_CHANGE.
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
UNICODE_STRING NullString = {0};
|
||
|
||
if (NULL == UnicodeStrings)
|
||
{
|
||
UnicodeStrings = &NullString;
|
||
}
|
||
|
||
UNREFERENCED_PARAMETER( UnicodeStringCount );
|
||
UNREFERENCED_PARAMETER( SidCount );
|
||
|
||
switch ( AuditEventCategory ) {
|
||
case SE_CATEGID_POLICY_CHANGE:
|
||
{
|
||
switch ( AuditEventId ) {
|
||
|
||
default:
|
||
DsysAssertMsg(FALSE, "LsapAdtGenerateLsaAuditEventWithClientSid: invalid AuditEventId");
|
||
break;
|
||
|
||
case SE_AUDITID_POLICY_CHANGE:
|
||
{
|
||
|
||
LsapAdtPolicyChange(
|
||
(USHORT)AuditEventCategory,
|
||
AuditEventId,
|
||
EVENTLOG_AUDIT_SUCCESS,
|
||
ClientSid,
|
||
ClientAuthenticationId,
|
||
PolicyAuditEventsInfo
|
||
);
|
||
break;
|
||
}
|
||
|
||
case SE_AUDITID_USER_RIGHT_ASSIGNED:
|
||
case SE_AUDITID_USER_RIGHT_REMOVED:
|
||
{
|
||
|
||
DsysAssertMsg( SidCount == 1,
|
||
"LsapAdtGenerateLsaAuditEventWithClientSid" );
|
||
LsapAdtUserRightAssigned(
|
||
(USHORT)AuditEventCategory,
|
||
AuditEventId,
|
||
EVENTLOG_AUDIT_SUCCESS,
|
||
ClientSid,
|
||
ClientAuthenticationId,
|
||
Sids[0],
|
||
Privileges
|
||
);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
break;
|
||
|
||
}
|
||
|
||
default:
|
||
{
|
||
DsysAssertMsg( FALSE, "LsapAdtGenerateLsaAuditEventWithClientSid: unsupported audit category" );
|
||
return( STATUS_SUCCESS );
|
||
}
|
||
}
|
||
|
||
|
||
return(Status);
|
||
}
|
||
|
||
|
||
VOID
|
||
LsapAdtUserRightAssigned(
|
||
IN USHORT EventCategory,
|
||
IN ULONG EventID,
|
||
IN USHORT EventType,
|
||
IN PSID ClientSid,
|
||
IN LUID CallerAuthenticationId,
|
||
IN PSID TargetSid,
|
||
IN PPRIVILEGE_SET Privileges
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generates an audit for a user right being either assigned or removed.
|
||
|
||
|
||
Arguments:
|
||
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
|
||
//
|
||
// Build an audit parameters structure.
|
||
//
|
||
|
||
RtlZeroMemory (
|
||
(PVOID) &AuditParameters,
|
||
sizeof( AuditParameters )
|
||
);
|
||
|
||
AuditParameters.CategoryId = EventCategory;
|
||
AuditParameters.AuditId = EventID;
|
||
AuditParameters.Type = EventType;
|
||
AuditParameters.ParameterCount = 0;
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, ClientSid );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Rights
|
||
//
|
||
|
||
LsapSetParmTypePrivileges( AuditParameters, AuditParameters.ParameterCount, Privileges );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Target Sid
|
||
//
|
||
|
||
LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, TargetSid );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Caller's Authentication information
|
||
//
|
||
|
||
LsapSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, CallerAuthenticationId );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
LsapAdtGenerateLsaAuditSystemAccessChange(
|
||
IN USHORT EventCategory,
|
||
IN ULONG EventID,
|
||
IN USHORT EventType,
|
||
IN PSID ClientSid,
|
||
IN LUID CallerAuthenticationId,
|
||
IN PSID TargetSid,
|
||
IN PCWSTR szSystemAccess
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generates an audit for System Security Access changes.
|
||
|
||
|
||
Arguments:
|
||
|
||
EventCategory - The category of this event
|
||
EventID - specific ID of event
|
||
EventType - success or failure
|
||
ClientSid - sid of client
|
||
CallerAuthenticationID - Logon ID of caller
|
||
TargetSid - receives access change
|
||
szSystemAccess - string describing which access changed
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
UNICODE_STRING SystemAccessString;
|
||
|
||
//
|
||
// Build an audit parameters structure.
|
||
//
|
||
|
||
RtlZeroMemory (
|
||
(PVOID) &AuditParameters,
|
||
sizeof( AuditParameters )
|
||
);
|
||
|
||
RtlInitUnicodeString( &SystemAccessString, szSystemAccess );
|
||
LsapAdtInitParametersArray( &AuditParameters,
|
||
EventCategory,
|
||
EventID,
|
||
EventType,
|
||
5,
|
||
SeAdtParmTypeSid, ClientSid,
|
||
SeAdtParmTypeString, &LsapSubsystemName,
|
||
SeAdtParmTypeLogonId, CallerAuthenticationId,
|
||
SeAdtParmTypeString, &SystemAccessString,
|
||
SeAdtParmTypeSid, TargetSid
|
||
);
|
||
|
||
(VOID) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtTrustedDomainAdd(
|
||
IN USHORT EventType,
|
||
IN PUNICODE_STRING pName,
|
||
IN PSID pSid,
|
||
IN ULONG Type,
|
||
IN ULONG Direction,
|
||
IN ULONG Attributes
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generate an audit event when a trusted domain object (TDO) is created.
|
||
|
||
Arguments:
|
||
|
||
EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
|
||
|
||
pName - name of the domain
|
||
|
||
pSid - domain SID
|
||
|
||
Type - TDO type
|
||
|
||
Direction - TDO direction
|
||
|
||
Attributes - TDO attributes
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code
|
||
|
||
Notes:
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
LUID ClientAuthenticationId;
|
||
PTOKEN_USER TokenUserInformation=NULL;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
|
||
|
||
//
|
||
// if auditing is not enabled, return asap
|
||
//
|
||
|
||
if ( !LsapAdtIsAuditingEnabledForCategory( AuditCategoryPolicyChange,
|
||
EventType ) )
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
Status = LsapQueryClientInfo( &TokenUserInformation, &ClientAuthenticationId );
|
||
|
||
if ( !NT_SUCCESS( Status ))
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Build an audit parameters structure.
|
||
//
|
||
|
||
LsapAdtInitParametersArray(
|
||
&AuditParameters,
|
||
SE_CATEGID_POLICY_CHANGE,
|
||
SE_AUDITID_TRUSTED_DOMAIN_ADD,
|
||
EventType,
|
||
8, // there are 8 params to init
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
SeAdtParmTypeSid, TokenUserInformation->User.Sid,
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
SeAdtParmTypeString, &LsapSubsystemName,
|
||
|
||
//
|
||
// domain name
|
||
//
|
||
|
||
SeAdtParmTypeString, pName,
|
||
|
||
//
|
||
// domain id
|
||
//
|
||
|
||
SeAdtParmTypeSid, pSid,
|
||
|
||
//
|
||
// client auth-id
|
||
//
|
||
|
||
SeAdtParmTypeLogonId, ClientAuthenticationId,
|
||
|
||
//
|
||
// TDO type
|
||
//
|
||
|
||
SeAdtParmTypeUlong, Type,
|
||
|
||
//
|
||
// TDO direction
|
||
//
|
||
|
||
SeAdtParmTypeUlong, Direction,
|
||
|
||
//
|
||
// TDO attributes
|
||
//
|
||
|
||
SeAdtParmTypeUlong, Attributes
|
||
|
||
);
|
||
|
||
Status = LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Cleanup:
|
||
|
||
if (TokenUserInformation != NULL)
|
||
{
|
||
LsapFreeLsaHeap( TokenUserInformation );
|
||
}
|
||
|
||
if (!NT_SUCCESS(Status))
|
||
{
|
||
LsapAuditFailed( Status );
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtTrustedDomainRem(
|
||
IN USHORT EventType,
|
||
IN PUNICODE_STRING pName,
|
||
IN PSID pSid,
|
||
IN PSID pClientSid,
|
||
IN PLUID pClientAuthId
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generate an audit event when a trusted domain object (TDO) is deleted.
|
||
|
||
Arguments:
|
||
|
||
EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
|
||
|
||
pName - name of the domain
|
||
|
||
pSid - domain SID
|
||
|
||
pClientSid - SID of the client who deleted the TDO
|
||
if NULL, it is determined from the thread token
|
||
|
||
pClientAuthId- auth-id of the client who deleted the TDO
|
||
if NULL, it is determined from the thread token
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code
|
||
|
||
Notes:
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
LUID ClientAuthenticationId;
|
||
PTOKEN_USER TokenUserInformation=NULL;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
|
||
|
||
|
||
//
|
||
// if auditing is not enabled, return asap
|
||
//
|
||
|
||
if ( !LsapAdtIsAuditingEnabledForCategory( AuditCategoryPolicyChange,
|
||
EventType ) )
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
if ( pClientSid == NULL )
|
||
{
|
||
DsysAssertMsg( pClientAuthId == NULL, "LsapAdtTrustedDomainRem" );
|
||
|
||
Status = LsapQueryClientInfo( &TokenUserInformation,
|
||
&ClientAuthenticationId );
|
||
|
||
if ( !NT_SUCCESS( Status ))
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
pClientSid = TokenUserInformation->User.Sid;
|
||
pClientAuthId = &ClientAuthenticationId;
|
||
}
|
||
#if DBG
|
||
else
|
||
{
|
||
DsysAssertMsg( pClientAuthId != NULL, "LsapAdtTrustedDomainRem" );
|
||
}
|
||
#endif
|
||
|
||
//
|
||
// Build an audit parameters structure.
|
||
//
|
||
|
||
LsapAdtInitParametersArray(
|
||
&AuditParameters,
|
||
SE_CATEGID_POLICY_CHANGE,
|
||
SE_AUDITID_TRUSTED_DOMAIN_REM,
|
||
EventType,
|
||
5, // there are 5 params to init
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
SeAdtParmTypeSid, pClientSid,
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
SeAdtParmTypeString, &LsapSubsystemName,
|
||
|
||
//
|
||
// domain name
|
||
//
|
||
|
||
SeAdtParmTypeString, pName,
|
||
|
||
//
|
||
// domain id (SID of the root domain)
|
||
//
|
||
|
||
SeAdtParmTypeSid, pSid,
|
||
|
||
//
|
||
// client auth-id
|
||
//
|
||
|
||
SeAdtParmTypeLogonId, *pClientAuthId
|
||
|
||
);
|
||
|
||
Status = LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Cleanup:
|
||
|
||
if (TokenUserInformation != NULL)
|
||
{
|
||
LsapFreeLsaHeap( TokenUserInformation );
|
||
}
|
||
|
||
if (!NT_SUCCESS(Status))
|
||
{
|
||
LsapAuditFailed( Status );
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtTrustedDomainMod(
|
||
IN USHORT EventType,
|
||
IN PSID pDomainSid,
|
||
|
||
IN PUNICODE_STRING pOldName,
|
||
IN ULONG OldType,
|
||
IN ULONG OldDirection,
|
||
IN ULONG OldAttributes,
|
||
|
||
IN PUNICODE_STRING pNewName,
|
||
IN ULONG NewType,
|
||
IN ULONG NewDirection,
|
||
IN ULONG NewAttributes
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generate an audit event when a trusted domain object (TDO) is modified.
|
||
the unmodified fields are represented by a '-' in the audit log.
|
||
|
||
Arguments:
|
||
|
||
EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
|
||
|
||
pOldName - old name of the domain
|
||
|
||
pOldSid - old domain SID
|
||
|
||
OldType - old TDO type
|
||
|
||
OldDirection - old TDO direction
|
||
|
||
OldAttributes - old TDO attributes
|
||
|
||
pNewName - new name of the domain
|
||
|
||
pNewSid - new domain SID
|
||
|
||
NewType - new TDO type
|
||
|
||
NewDirection - new TDO direction
|
||
|
||
NewAttributes - new TDO attributes
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code
|
||
|
||
Notes:
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
LUID ClientAuthenticationId;
|
||
PTOKEN_USER TokenUserInformation=NULL;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
|
||
UNICODE_STRING TempName;
|
||
|
||
//
|
||
// if auditing is not enabled, return asap
|
||
//
|
||
|
||
if ( !LsapAdtIsAuditingEnabledForCategory( AuditCategoryPolicyChange,
|
||
EventType ) )
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
Status = LsapQueryClientInfo( &TokenUserInformation, &ClientAuthenticationId );
|
||
|
||
if ( !NT_SUCCESS( Status ))
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
AuditParameters.CategoryId = SE_CATEGID_POLICY_CHANGE;
|
||
AuditParameters.AuditId = SE_AUDITID_TRUSTED_DOMAIN_MOD;
|
||
AuditParameters.Type = EventType;
|
||
AuditParameters.ParameterCount = 8;
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
LsapSetParmTypeSid( AuditParameters, 0, TokenUserInformation->User.Sid );
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
LsapSetParmTypeString( AuditParameters, 1, &LsapSubsystemName );
|
||
|
||
|
||
//
|
||
// for all subsequent fields (except the domain SID),
|
||
// output a value only if it changed.
|
||
//
|
||
|
||
//
|
||
// domain name
|
||
//
|
||
|
||
if ( pOldName && pNewName &&
|
||
!RtlEqualUnicodeString( pOldName, pNewName, TRUE ) )
|
||
{
|
||
LsapSetParmTypeString( AuditParameters, 2, pNewName );
|
||
}
|
||
|
||
//
|
||
// domain id
|
||
//
|
||
|
||
LsapSetParmTypeSid( AuditParameters, 3, pDomainSid );
|
||
|
||
//
|
||
// client auth-id
|
||
//
|
||
|
||
LsapSetParmTypeLogonId( AuditParameters, 4, ClientAuthenticationId );
|
||
|
||
//
|
||
// TDO type
|
||
//
|
||
|
||
if ( OldType != NewType )
|
||
{
|
||
LsapSetParmTypeUlong( AuditParameters, 5, NewType );
|
||
}
|
||
|
||
//
|
||
// TDO direction
|
||
//
|
||
|
||
if ( OldDirection != NewDirection )
|
||
{
|
||
LsapSetParmTypeUlong( AuditParameters, 6, NewDirection );
|
||
}
|
||
|
||
//
|
||
// TDO attributes
|
||
//
|
||
|
||
if ( OldAttributes != NewAttributes )
|
||
{
|
||
LsapSetParmTypeUlong( AuditParameters, 7, NewAttributes );
|
||
}
|
||
|
||
|
||
|
||
Status = LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Cleanup:
|
||
|
||
if (TokenUserInformation != NULL)
|
||
{
|
||
LsapFreeLsaHeap( TokenUserInformation );
|
||
}
|
||
|
||
if (!NT_SUCCESS(Status))
|
||
{
|
||
LsapAuditFailed( Status );
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtTrustedForestNamespaceCollision(
|
||
IN LSA_FOREST_TRUST_COLLISION_RECORD_TYPE CollisionTargetType,
|
||
IN PUNICODE_STRING pCollisionTargetName,
|
||
IN PUNICODE_STRING pForestRootDomainName,
|
||
IN PUNICODE_STRING pTopLevelName,
|
||
IN PUNICODE_STRING pDnsName,
|
||
IN PUNICODE_STRING pNetbiosName,
|
||
IN PSID pSid,
|
||
IN ULONG NewFlags
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function generates the audit event that represents
|
||
a namespace element collision.
|
||
|
||
|
||
Arguments:
|
||
|
||
CollisionTargetType - type of the collision target
|
||
CollisionTdo : indicates a collision with a namespace element of
|
||
another forest
|
||
CollisionXref : indicates a collision with a domain in our forest
|
||
|
||
pCollisionTargetName -
|
||
name of the collision target (TDO name or Xref name)
|
||
|
||
pForestRootDomainName - name of other forest
|
||
|
||
pTopLevelName - top level name (NULL == not in conflict)
|
||
|
||
pDnsName - DNS domain name (this is NULL is TLN is non-NULL)
|
||
|
||
pNetbiosName - NetBIOS name (NULL == not in conflict)
|
||
|
||
pSid - SID of domain (NULL == not in conflict)
|
||
|
||
NewFlags - the new value of flags
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code
|
||
|
||
Notes:
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
|
||
#if DBG
|
||
HANDLE hToken;
|
||
#endif
|
||
DsysAssert(( CollisionTargetType == CollisionTdo ) ||
|
||
( CollisionTargetType == CollisionXref));
|
||
DsysAssert( pCollisionTargetName != NULL );
|
||
DsysAssert( pForestRootDomainName != NULL );
|
||
|
||
#if DBG
|
||
if ( pTopLevelName )
|
||
{
|
||
DsysAssert( pDnsName == NULL );
|
||
DsysAssert( pNetbiosName == NULL );
|
||
DsysAssert( pSid == NULL );
|
||
}
|
||
else
|
||
{
|
||
DsysAssert( pDnsName != NULL );
|
||
|
||
if ( pNetbiosName != NULL )
|
||
{
|
||
DsysAssert( pSid == NULL );
|
||
}
|
||
|
||
if ( pSid != NULL )
|
||
{
|
||
DsysAssert( pNetbiosName == NULL );
|
||
}
|
||
}
|
||
#endif
|
||
|
||
//
|
||
// if auditing is not enabled, return asap
|
||
//
|
||
|
||
if ( !LsapAdtIsAuditingEnabledForCategory( AuditCategoryPolicyChange,
|
||
EVENTLOG_AUDIT_SUCCESS ) )
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
#if DBG
|
||
//
|
||
// make sure that this is called in the system context
|
||
//
|
||
|
||
Status = NtOpenThreadToken( NtCurrentThread(), TOKEN_QUERY, TRUE, &hToken );
|
||
|
||
DsysAssertMsg( Status == STATUS_NO_TOKEN, "LsapAdtTrustedForestNamespaceCollision" );
|
||
|
||
if ( NT_SUCCESS(Status) )
|
||
{
|
||
NtClose( hToken );
|
||
}
|
||
else
|
||
{
|
||
Status = STATUS_SUCCESS;
|
||
}
|
||
|
||
#endif
|
||
|
||
//
|
||
// Build an audit parameters structure.
|
||
//
|
||
|
||
LsapAdtInitParametersArray(
|
||
&AuditParameters,
|
||
SE_CATEGID_POLICY_CHANGE,
|
||
SE_AUDITID_NAMESPACE_COLLISION,
|
||
EVENTLOG_AUDIT_SUCCESS,
|
||
|
||
//
|
||
// number of params to follow
|
||
//
|
||
|
||
10,
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
SeAdtParmTypeSid, LsapLocalSystemSid,
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
SeAdtParmTypeString, &LsapSubsystemName,
|
||
|
||
//
|
||
// collision target type
|
||
//
|
||
// 0 == CollisionTdo
|
||
// 1 == CollisionXref
|
||
//
|
||
|
||
SeAdtParmTypeUlong, CollisionTargetType,
|
||
|
||
//
|
||
// collision target name
|
||
//
|
||
// name of a TDO or cross-ref
|
||
//
|
||
|
||
SeAdtParmTypeString, pCollisionTargetName,
|
||
|
||
//
|
||
// Name of forest involved in the collision
|
||
//
|
||
|
||
SeAdtParmTypeString, pForestRootDomainName,
|
||
|
||
//
|
||
// top level name
|
||
//
|
||
|
||
SeAdtParmTypeString, pTopLevelName,
|
||
|
||
//
|
||
// DNS name
|
||
//
|
||
|
||
SeAdtParmTypeString, pDnsName,
|
||
|
||
//
|
||
// NetBIOS name
|
||
//
|
||
|
||
SeAdtParmTypeString, pNetbiosName,
|
||
|
||
//
|
||
// SID
|
||
//
|
||
|
||
SeAdtParmTypeSid, pSid,
|
||
|
||
//
|
||
// new flags value
|
||
//
|
||
|
||
SeAdtParmTypeUlong, NewFlags
|
||
|
||
);
|
||
|
||
Status = LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Cleanup:
|
||
if (!NT_SUCCESS(Status))
|
||
{
|
||
LsapAuditFailed( Status );
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtTrustedForestInfoEntryAddRemHelper(
|
||
IN ULONG EventId,
|
||
IN USHORT EventType,
|
||
IN PUNICODE_STRING ForestName,
|
||
IN PSID pForestRootDomainSid,
|
||
IN PLUID pOperationId,
|
||
IN LSA_FOREST_TRUST_RECORD_TYPE EntryType,
|
||
IN ULONG Flags,
|
||
IN PUNICODE_STRING TopLevelName,
|
||
IN PUNICODE_STRING DnsName,
|
||
IN PUNICODE_STRING NetbiosName,
|
||
IN PSID pSid
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Helper function for generating audit event when a namespace
|
||
element has been added to / removed from forest trust info.
|
||
If multiple entries get added, deleted or modified
|
||
in a single update of the forest trust information, all the generated
|
||
audit events will have a single unique identifier called OperationID.
|
||
This allows one to determine that the multiple generated audits are
|
||
the result of a single operation.
|
||
|
||
Arguments:
|
||
|
||
EventId - SE_AUDITID_TRUSTED_FOREST_INFO_ENTRY_ADD/REM
|
||
|
||
EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
|
||
|
||
ForestName - name of the forest
|
||
|
||
pForestRootDomainSid - SID of the forest
|
||
|
||
pOperationId - operation id (see description above)
|
||
|
||
EntryType - type of entry ( TLN | TLN excl. | domain info )
|
||
|
||
Flags - flags associated with the entry ( see ntlsa.h )
|
||
|
||
TopLevelName - TopLevel name
|
||
|
||
DnsName - Dns name
|
||
|
||
NetbiosName - Netbios name
|
||
|
||
pSid - domain sid
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code
|
||
|
||
Notes:
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
LUID ClientAuthenticationId;
|
||
PTOKEN_USER TokenUserInformation=NULL;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
|
||
|
||
//
|
||
// if auditing is not enabled, return asap
|
||
//
|
||
|
||
if ( !LsapAdtIsAuditingEnabledForCategory( AuditCategoryPolicyChange,
|
||
EventType ) )
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
Status = LsapQueryClientInfo( &TokenUserInformation, &ClientAuthenticationId );
|
||
|
||
if ( !NT_SUCCESS( Status ))
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Build an audit parameters structure.
|
||
//
|
||
|
||
LsapAdtInitParametersArray(
|
||
&AuditParameters,
|
||
SE_CATEGID_POLICY_CHANGE,
|
||
EventId,
|
||
EventType,
|
||
|
||
//
|
||
// number of params to follow
|
||
//
|
||
|
||
13,
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
SeAdtParmTypeSid, TokenUserInformation->User.Sid,
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
SeAdtParmTypeString, &LsapSubsystemName,
|
||
|
||
//
|
||
// Forest name
|
||
//
|
||
|
||
SeAdtParmTypeString, ForestName,
|
||
|
||
//
|
||
// Forest SID
|
||
//
|
||
|
||
SeAdtParmTypeSid, pForestRootDomainSid,
|
||
|
||
//
|
||
// Operation ID
|
||
//
|
||
|
||
SeAdtParmTypeUlong, pOperationId->HighPart,
|
||
SeAdtParmTypeUlong, pOperationId->LowPart,
|
||
|
||
//
|
||
// Entry Type
|
||
//
|
||
|
||
SeAdtParmTypeUlong, EntryType,
|
||
|
||
//
|
||
// Flags
|
||
//
|
||
|
||
SeAdtParmTypeUlong, Flags,
|
||
|
||
//
|
||
// top level name
|
||
//
|
||
|
||
SeAdtParmTypeString, TopLevelName,
|
||
|
||
//
|
||
// DNS domain name
|
||
//
|
||
|
||
SeAdtParmTypeString, DnsName,
|
||
|
||
//
|
||
// NetBIOS domain name
|
||
//
|
||
|
||
SeAdtParmTypeString, NetbiosName,
|
||
|
||
//
|
||
// domain SID
|
||
//
|
||
|
||
SeAdtParmTypeSid, pSid,
|
||
|
||
//
|
||
// user info
|
||
//
|
||
|
||
SeAdtParmTypeLogonId, ClientAuthenticationId
|
||
);
|
||
|
||
Status = LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Cleanup:
|
||
|
||
if (TokenUserInformation != NULL)
|
||
{
|
||
LsapFreeLsaHeap( TokenUserInformation );
|
||
}
|
||
|
||
if (!NT_SUCCESS(Status))
|
||
{
|
||
LsapAuditFailed( Status );
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtTrustedForestInfoEntryAdd(
|
||
IN PUNICODE_STRING pForestRootDomainName,
|
||
IN PSID pForestRootDomainSid,
|
||
IN PLUID pOperationId,
|
||
IN LSA_FOREST_TRUST_RECORD_TYPE EntryType,
|
||
IN ULONG Flags,
|
||
IN PUNICODE_STRING TopLevelName,
|
||
IN PUNICODE_STRING DnsName,
|
||
IN PUNICODE_STRING NetbiosName,
|
||
IN PSID pSid
|
||
)
|
||
{
|
||
return LsapAdtTrustedForestInfoEntryAddRemHelper(
|
||
SE_AUDITID_TRUSTED_FOREST_INFO_ENTRY_ADD,
|
||
EVENTLOG_AUDIT_SUCCESS,
|
||
pForestRootDomainName,
|
||
pForestRootDomainSid,
|
||
pOperationId,
|
||
EntryType,
|
||
Flags,
|
||
TopLevelName,
|
||
DnsName,
|
||
NetbiosName,
|
||
pSid
|
||
);
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtTrustedForestInfoEntryRem(
|
||
IN PUNICODE_STRING pForestRootDomainName,
|
||
IN PSID pForestRootDomainSid,
|
||
IN PLUID pOperationId,
|
||
IN LSA_FOREST_TRUST_RECORD_TYPE EntryType,
|
||
IN ULONG Flags,
|
||
IN PUNICODE_STRING TopLevelName,
|
||
IN PUNICODE_STRING DnsName,
|
||
IN PUNICODE_STRING NetbiosName,
|
||
IN PSID pSid
|
||
)
|
||
{
|
||
return LsapAdtTrustedForestInfoEntryAddRemHelper(
|
||
SE_AUDITID_TRUSTED_FOREST_INFO_ENTRY_REM,
|
||
EVENTLOG_AUDIT_SUCCESS,
|
||
pForestRootDomainName,
|
||
pForestRootDomainSid,
|
||
pOperationId,
|
||
EntryType,
|
||
Flags,
|
||
TopLevelName,
|
||
DnsName,
|
||
NetbiosName,
|
||
pSid
|
||
);
|
||
}
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtTrustedForestInfoEntryMod(
|
||
IN PUNICODE_STRING pForestRootDomainName,
|
||
IN PSID pForestRootDomainSid,
|
||
IN PLUID pOperationId,
|
||
IN LSA_FOREST_TRUST_RECORD_TYPE EntryType,
|
||
|
||
IN ULONG OldFlags,
|
||
IN PUNICODE_STRING pOldTopLevelName,
|
||
IN PUNICODE_STRING pOldDnsName,
|
||
IN PUNICODE_STRING pOldNetbiosName,
|
||
IN PSID pOldSid,
|
||
|
||
IN ULONG NewFlags,
|
||
IN PUNICODE_STRING pNewTopLevelName,
|
||
IN PUNICODE_STRING pNewDnsName,
|
||
IN PUNICODE_STRING pNewNetbiosName,
|
||
IN PSID pNewSid
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Helper function for generating audit event when a namespace
|
||
element in forest trust info has been modified.
|
||
If multiple entries get added, deleted or modified
|
||
in a single update of the forest trust information, all the generated
|
||
audit events will have a single unique identifier called OperationID.
|
||
This allows one to determine that the multiple generated audits are
|
||
the result of a single operation.
|
||
|
||
Arguments:
|
||
|
||
EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
|
||
|
||
ForestName - name of the forest
|
||
|
||
pForestRootDomainSid - SID of the forest
|
||
|
||
pOperationId - operation id (see description above)
|
||
|
||
EntryType - type of entry ( TLN | TLN excl. | domain info )
|
||
|
||
OldFlags - old flags associated with the entry ( see ntlsa.h )
|
||
|
||
pOldTopLevelName - old TopLevel name
|
||
|
||
pOldDnsName - old Dns name
|
||
|
||
pOldNetbiosName - old Netbios name
|
||
|
||
pOldSid - old domain sid
|
||
|
||
NewFlags - new flags associated with the entry ( see ntlsa.h )
|
||
|
||
pNewTopLevelName - new TopLevel name
|
||
|
||
pNewDnsName - new Dns name
|
||
|
||
pNewNetbiosName - new Netbios name
|
||
|
||
pNewSid - new domain sid
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code
|
||
|
||
Notes:
|
||
|
||
The unmodified fields are represented by a '-' in the audit log.
|
||
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
LUID ClientAuthenticationId;
|
||
PTOKEN_USER TokenUserInformation=NULL;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
|
||
|
||
//
|
||
// if auditing is not enabled, return asap
|
||
//
|
||
|
||
if ( !LsapAdtIsAuditingEnabledForCategory( AuditCategoryPolicyChange,
|
||
EVENTLOG_AUDIT_SUCCESS ) )
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
Status = LsapQueryClientInfo( &TokenUserInformation, &ClientAuthenticationId );
|
||
|
||
if ( !NT_SUCCESS( Status ))
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
AuditParameters.CategoryId = SE_CATEGID_POLICY_CHANGE;
|
||
AuditParameters.AuditId = SE_AUDITID_TRUSTED_FOREST_INFO_ENTRY_MOD;
|
||
AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
|
||
AuditParameters.ParameterCount = 13;
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
LsapSetParmTypeSid( AuditParameters, 0, TokenUserInformation->User.Sid );
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
LsapSetParmTypeString( AuditParameters, 1, &LsapSubsystemName );
|
||
|
||
|
||
//
|
||
// forest name
|
||
//
|
||
|
||
LsapSetParmTypeString( AuditParameters, 2, pForestRootDomainName );
|
||
|
||
//
|
||
// forest id (SID of the root domain)
|
||
//
|
||
|
||
LsapSetParmTypeSid( AuditParameters, 3, pForestRootDomainSid );
|
||
|
||
//
|
||
// Operation ID
|
||
//
|
||
|
||
LsapSetParmTypeUlong( AuditParameters, 4, pOperationId->HighPart );
|
||
LsapSetParmTypeUlong( AuditParameters, 5, pOperationId->LowPart );
|
||
|
||
//
|
||
// entry type
|
||
//
|
||
|
||
LsapSetParmTypeUlong( AuditParameters, 6, EntryType );
|
||
|
||
//
|
||
// for all subsequent types, output a value only if it changed.
|
||
//
|
||
|
||
//
|
||
// Flags
|
||
//
|
||
|
||
if ( OldFlags != NewFlags )
|
||
{
|
||
LsapSetParmTypeUlong( AuditParameters, 7, NewFlags );
|
||
}
|
||
|
||
//
|
||
// top level name
|
||
//
|
||
|
||
if ( pOldTopLevelName && pNewTopLevelName &&
|
||
!RtlEqualUnicodeString( pOldTopLevelName, pNewTopLevelName, TRUE ) )
|
||
{
|
||
LsapSetParmTypeString( AuditParameters, 8, pNewTopLevelName );
|
||
}
|
||
|
||
//
|
||
// DNS domain name
|
||
//
|
||
|
||
if ( pOldDnsName && pNewDnsName &&
|
||
!RtlEqualUnicodeString( pOldDnsName, pNewDnsName, TRUE ) )
|
||
{
|
||
LsapSetParmTypeString( AuditParameters, 9, pNewDnsName );
|
||
}
|
||
|
||
//
|
||
// NetBIOS domain name
|
||
//
|
||
|
||
if ( pOldNetbiosName && pNewNetbiosName &&
|
||
!RtlEqualUnicodeString( pOldNetbiosName, pNewNetbiosName, TRUE ) )
|
||
{
|
||
LsapSetParmTypeString( AuditParameters, 10, pNewNetbiosName );
|
||
}
|
||
|
||
//
|
||
// domain SID
|
||
//
|
||
|
||
if ( pOldSid && pNewSid && !RtlEqualSid( pOldSid, pNewSid ) )
|
||
{
|
||
LsapSetParmTypeSid( AuditParameters, 11, pNewSid );
|
||
}
|
||
|
||
//
|
||
// client auth-id
|
||
//
|
||
|
||
LsapSetParmTypeLogonId( AuditParameters, 12, ClientAuthenticationId );
|
||
|
||
|
||
Status = LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Cleanup:
|
||
|
||
if (TokenUserInformation != NULL)
|
||
{
|
||
LsapFreeLsaHeap( TokenUserInformation );
|
||
}
|
||
|
||
if (!NT_SUCCESS(Status))
|
||
{
|
||
LsapAuditFailed( Status );
|
||
}
|
||
|
||
return Status;
|
||
|
||
}
|
||
|
||
|
||
|
||
VOID
|
||
LsapAdtPolicyChange(
|
||
IN USHORT EventCategory,
|
||
IN ULONG EventID,
|
||
IN USHORT EventType,
|
||
IN PSID ClientSid,
|
||
IN LUID CallerAuthenticationId,
|
||
IN PLSARM_POLICY_AUDIT_EVENTS_INFO PolicyAuditEventsInfo
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generates an audit for a policy change event.
|
||
|
||
Arguments:
|
||
|
||
EventCategory - The category of this audit.
|
||
|
||
EventID - The event we are auditing.
|
||
|
||
EventType - Whether the audit is success or failure.
|
||
|
||
ClientSid - The SID of the user performing the policy change.
|
||
|
||
CallerAuthenticationId - The Authentication id of the user.
|
||
|
||
PolicyAuditEventsInfo - The information to audit.
|
||
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
Note:
|
||
--*/
|
||
{
|
||
PPOLICY_AUDIT_EVENT_OPTIONS EventAuditingOptions;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
UNICODE_STRING Enabled;
|
||
UNICODE_STRING Disabled;
|
||
ULONG i;
|
||
|
||
RtlInitUnicodeString( &Enabled, L"+" );
|
||
RtlInitUnicodeString( &Disabled, L"-" );
|
||
EventAuditingOptions = PolicyAuditEventsInfo->EventAuditingOptions;
|
||
|
||
//
|
||
// Build an audit parameters structure.
|
||
//
|
||
|
||
RtlZeroMemory (
|
||
(PVOID) &AuditParameters,
|
||
sizeof( AuditParameters )
|
||
);
|
||
|
||
AuditParameters.CategoryId = EventCategory;
|
||
AuditParameters.AuditId = EventID;
|
||
AuditParameters.Type = EventType;
|
||
AuditParameters.ParameterCount = 0;
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, ClientSid );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// If auditing is disabled, mark all options as disabled. Otherwise
|
||
// mark them as the appropriate
|
||
//
|
||
|
||
if (PolicyAuditEventsInfo->AuditingMode) {
|
||
for ( i=0; i<POLICY_AUDIT_EVENT_TYPE_COUNT; i++ ) {
|
||
|
||
LsapSetParmTypeString(
|
||
AuditParameters,
|
||
AuditParameters.ParameterCount,
|
||
(EventAuditingOptions[i] & POLICY_AUDIT_EVENT_SUCCESS ? &Enabled : &Disabled)
|
||
);
|
||
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeString(
|
||
AuditParameters,
|
||
AuditParameters.ParameterCount,
|
||
(EventAuditingOptions[i] & POLICY_AUDIT_EVENT_FAILURE ? &Enabled : &Disabled)
|
||
);
|
||
|
||
AuditParameters.ParameterCount++;
|
||
}
|
||
} else {
|
||
//
|
||
// Auditing is disabled - mark them all disabled.
|
||
//
|
||
|
||
for ( i=0; i<POLICY_AUDIT_EVENT_TYPE_COUNT; i++ ) {
|
||
|
||
LsapSetParmTypeString(
|
||
AuditParameters,
|
||
AuditParameters.ParameterCount,
|
||
&Disabled
|
||
);
|
||
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeString(
|
||
AuditParameters,
|
||
AuditParameters.ParameterCount,
|
||
&Disabled
|
||
);
|
||
|
||
AuditParameters.ParameterCount++;
|
||
}
|
||
|
||
}
|
||
|
||
//
|
||
// Caller's Authentication information
|
||
//
|
||
|
||
LsapSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, CallerAuthenticationId );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
NTSTATUS
|
||
LsapAdtGenerateDomainPolicyChangeAuditEvent(
|
||
IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
|
||
IN USHORT AuditEventType,
|
||
IN LSAP_DB_ATTRIBUTE* OldAttributes,
|
||
IN LSAP_DB_ATTRIBUTE* NewAttributes,
|
||
IN ULONG AttributeCount
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generate an audit event when any of the following policies changes:
|
||
- PolicyDomainEfsInformation
|
||
- PolicyDomainKerberosTicketInformation
|
||
|
||
Arguments:
|
||
|
||
InformationClass - type of policy that changed
|
||
|
||
AuditEventType - The type of audit event to be generated.
|
||
EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
|
||
|
||
OldAttributes - pointer to array of old attributes
|
||
|
||
NewAttributes - pointer to array of new attributes
|
||
|
||
AttributeCount - number of attributes
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code
|
||
|
||
Notes:
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status=STATUS_SUCCESS;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
ULONG AuditId;
|
||
LPWSTR AttributeChanges=NULL;
|
||
UNICODE_STRING ChangesToAttributes;
|
||
LUID ClientAuthenticationId;
|
||
PTOKEN_USER TokenUserInformation=NULL;
|
||
|
||
AuditId=0; // to get rid of uninit var warning
|
||
|
||
Status = LsapQueryClientInfo(
|
||
&TokenUserInformation,
|
||
&ClientAuthenticationId
|
||
);
|
||
|
||
if ( !NT_SUCCESS( Status )) {
|
||
goto Cleanup;
|
||
}
|
||
|
||
switch (InformationClass) {
|
||
default:
|
||
ASSERT(FALSE);
|
||
goto Cleanup;
|
||
break;
|
||
|
||
case PolicyDomainEfsInformation:
|
||
AuditId = SE_AUDITID_EFS_POLICY_CHANGE;
|
||
break;
|
||
|
||
case PolicyDomainKerberosTicketInformation:
|
||
AuditId = SE_AUDITID_KERBEROS_POLICY_CHANGE;
|
||
break;
|
||
}
|
||
|
||
Status = LsapAdtGetDbAttributesChangeString( OldAttributes,
|
||
NewAttributes,
|
||
AttributeCount,
|
||
&AttributeChanges );
|
||
if (!NT_SUCCESS(Status)) {
|
||
goto Cleanup;
|
||
}
|
||
|
||
RtlInitUnicodeString(&ChangesToAttributes, AttributeChanges);
|
||
|
||
LsapAdtInitParametersArray(
|
||
&AuditParameters,
|
||
SE_CATEGID_POLICY_CHANGE,
|
||
AuditId,
|
||
AuditEventType,
|
||
4,
|
||
//
|
||
// User Sid
|
||
//
|
||
SeAdtParmTypeSid, TokenUserInformation->User.Sid,
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
SeAdtParmTypeString, &LsapSubsystemName,
|
||
|
||
//
|
||
// Caller's Authentication information
|
||
//
|
||
SeAdtParmTypeLogonId, ClientAuthenticationId,
|
||
|
||
//
|
||
// Changes to attributes
|
||
//
|
||
SeAdtParmTypeString, &ChangesToAttributes);
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Cleanup:
|
||
|
||
if (TokenUserInformation != NULL)
|
||
{
|
||
LsapFreeLsaHeap( TokenUserInformation );
|
||
}
|
||
|
||
LsapFreeLsaHeap( AttributeChanges );
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
void LsapAdtGetAttributeValueString(
|
||
IN LSAP_DB_ATTRIBUTE* Attribute,
|
||
OUT LPWSTR ValueString)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generate a string representation of the value of an attribute
|
||
|
||
Arguments:
|
||
|
||
Attribute - pointer to attribute
|
||
|
||
ValueString - receives a string representation of the value of Attribute
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
Notes:
|
||
|
||
--*/
|
||
{
|
||
if (Attribute->AttributeValue) {
|
||
|
||
switch (Attribute->DbNameIndex) {
|
||
|
||
default:
|
||
lstrcpy(ValueString, L"unknown");
|
||
break;
|
||
|
||
// binary blob
|
||
case PolEfDat:
|
||
lstrcpy(ValueString, L"<binary data>");
|
||
break;
|
||
|
||
// ULONG
|
||
case KerOpts:
|
||
swprintf(ValueString, L"0x%x", *((ULONG*) Attribute->AttributeValue));
|
||
break;
|
||
|
||
// LARGE_INTEGER
|
||
case KerMinT:
|
||
case KerMaxT:
|
||
case KerMaxR:
|
||
case KerProxy:
|
||
case KerLogoff:
|
||
swprintf(ValueString, L"0x%I64x",
|
||
*((ULONGLONG*) Attribute->AttributeValue));
|
||
break;
|
||
}
|
||
} else {
|
||
lstrcpy(ValueString, L"none");
|
||
}
|
||
}
|
||
|
||
|
||
void
|
||
LsapAdtGetDbAttributeChangeString(
|
||
IN LSAP_DB_ATTRIBUTE* OldAttribute,
|
||
IN LSAP_DB_ATTRIBUTE* NewAttribute,
|
||
OUT LPWSTR AttributeChangeString, OPTIONAL
|
||
IN OUT PULONG RequiredLength
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Given an old attribute and a new attribute, return
|
||
a string representation of the difference between the two.
|
||
|
||
If there are no changes, RequiredLength is returned as 0
|
||
and AttributeChangeString is left unchanged;
|
||
otherwise if AttributeChangeString is non-NULL, the change is
|
||
written to it as:
|
||
<ParameterName>: <new value> (<old value>)
|
||
|
||
Arguments:
|
||
|
||
OldAttribute - pointer to old attribute
|
||
|
||
NewAttribute - pointer to new attribute
|
||
|
||
AttributeChangeString - if non-NULL, receives the string representation
|
||
of the difference between OldAttribute and NewAttribute
|
||
|
||
RequiredLength - pointer to length of AttributeChangeString
|
||
|
||
Return Value:
|
||
|
||
None
|
||
|
||
Notes:
|
||
|
||
--*/
|
||
{
|
||
WCHAR ChangeString[256];
|
||
LPWSTR TmpString;
|
||
ULONG ChangeStringLength=0;
|
||
|
||
//
|
||
// do the processing only if there is a change in value
|
||
//
|
||
if ((OldAttribute->AttributeValue && NewAttribute->AttributeValue &&
|
||
(0 != memcmp(OldAttribute->AttributeValue,
|
||
NewAttribute->AttributeValue,
|
||
OldAttribute->AttributeValueLength))) ||
|
||
(OldAttribute->AttributeValue && !NewAttribute->AttributeValue) ||
|
||
(!OldAttribute->AttributeValue && NewAttribute->AttributeValue)) {
|
||
|
||
//
|
||
// Parameter Name
|
||
//
|
||
lstrcpy(ChangeString, OldAttribute->AttributeName->Buffer);
|
||
ChangeStringLength = OldAttribute->AttributeName->Length/sizeof(WCHAR);
|
||
TmpString = ChangeString + ChangeStringLength;
|
||
|
||
lstrcpy(TmpString, L": ");
|
||
ChangeStringLength += 2;
|
||
TmpString = ChangeString + ChangeStringLength;
|
||
|
||
//
|
||
// Old value
|
||
//
|
||
LsapAdtGetAttributeValueString( NewAttribute, TmpString );
|
||
ChangeStringLength += lstrlen(TmpString);
|
||
TmpString = ChangeString + ChangeStringLength;
|
||
|
||
//
|
||
// New value
|
||
//
|
||
lstrcpy(TmpString, L" (");
|
||
ChangeStringLength += 2;
|
||
TmpString = ChangeString + ChangeStringLength;
|
||
|
||
LsapAdtGetAttributeValueString( OldAttribute, TmpString );
|
||
ChangeStringLength += lstrlen(TmpString);
|
||
TmpString = ChangeString + ChangeStringLength;
|
||
|
||
lstrcpy(TmpString, L"); ");
|
||
ChangeStringLength += 4;
|
||
|
||
if (AttributeChangeString && (ChangeStringLength <= *RequiredLength)) {
|
||
lstrcpy(AttributeChangeString, ChangeString);
|
||
}
|
||
}
|
||
|
||
*RequiredLength = ChangeStringLength;
|
||
}
|
||
|
||
NTSTATUS
|
||
LsapAdtGetDbAttributesChangeString(
|
||
IN LSAP_DB_ATTRIBUTE* OldAttributes,
|
||
IN LSAP_DB_ATTRIBUTE* NewAttributes,
|
||
IN ULONG AttributeCount,
|
||
OUT LPWSTR* AttributeChangeString
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Given old attributes and new attributes, return a string representation
|
||
of the difference between old and new attributes.
|
||
|
||
If there are no changes, "--" is returned,
|
||
otherwise each change is written to the string as:
|
||
<ParameterName>: <new value> (<old value>)
|
||
|
||
This function is used for writing information about
|
||
changes to certain policies to the audit log.
|
||
|
||
Arguments:
|
||
|
||
OldAttributes - pointer to array of old attributes
|
||
|
||
NewAttributes - pointer to array of new attributes
|
||
|
||
AttributeCount - Number of attributes.
|
||
|
||
AttributeChangeString - pointer to string that receives the diff.
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code
|
||
|
||
Notes:
|
||
|
||
Memory allocated for AttributeChangeString must be freed by the
|
||
caller using LsapFreeLsaHeap.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status=STATUS_SUCCESS;
|
||
LSAP_DB_ATTRIBUTE* OldAttribute;
|
||
LSAP_DB_ATTRIBUTE* NewAttribute;
|
||
ULONG TmpStringLength;
|
||
ULONG TotalRequiredLength;
|
||
LPWSTR TmpString;
|
||
UINT AttributeNumber;
|
||
USHORT n=1;
|
||
|
||
OldAttribute = OldAttributes;
|
||
NewAttribute = NewAttributes;
|
||
|
||
TotalRequiredLength = 0;
|
||
|
||
//
|
||
// first find out the size of the buffer required
|
||
//
|
||
for (AttributeNumber = 0; AttributeNumber < AttributeCount; AttributeNumber++) {
|
||
|
||
LsapAdtGetDbAttributeChangeString( OldAttribute, NewAttribute,
|
||
NULL, &TmpStringLength );
|
||
OldAttribute++;
|
||
NewAttribute++;
|
||
TotalRequiredLength += TmpStringLength;
|
||
}
|
||
|
||
if (!TotalRequiredLength) {
|
||
n += 2;
|
||
}
|
||
|
||
*AttributeChangeString = TmpString =
|
||
LsapAllocateLsaHeap((TotalRequiredLength+n)*sizeof(WCHAR));
|
||
|
||
if ( TmpString ) {
|
||
|
||
if (TotalRequiredLength) {
|
||
|
||
//
|
||
// Now get the actual string
|
||
//
|
||
OldAttribute = OldAttributes;
|
||
NewAttribute = NewAttributes;
|
||
|
||
for (AttributeNumber = 0;
|
||
AttributeNumber < AttributeCount;
|
||
AttributeNumber++) {
|
||
|
||
TmpStringLength = TotalRequiredLength;
|
||
LsapAdtGetDbAttributeChangeString( OldAttribute, NewAttribute,
|
||
TmpString, &TmpStringLength );
|
||
TmpString += TmpStringLength;
|
||
OldAttribute++;
|
||
NewAttribute++;
|
||
}
|
||
} else {
|
||
lstrcpy(TmpString, L"--");
|
||
}
|
||
} else {
|
||
Status = STATUS_NO_MEMORY;
|
||
}
|
||
|
||
return Status;
|
||
}
|
||
|
||
|
||
VOID
|
||
LsapAdtAuditDiscardedAudits(
|
||
ULONG NumberOfEventsDiscarded
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Audits the fact that we discarded some audits.
|
||
|
||
Arguments:
|
||
|
||
NumberOfEventsDiscarded - The number of events discarded.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
||
NTSTATUS Status;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
|
||
if ( !LsapAdtEventsInformation.AuditingMode ) {
|
||
return;
|
||
}
|
||
|
||
if (!(LsapAdtEventsInformation.EventAuditingOptions[AuditCategorySystem] &
|
||
POLICY_AUDIT_EVENT_SUCCESS)) {
|
||
return;
|
||
}
|
||
|
||
RtlZeroMemory ((PVOID) &AuditParameters, sizeof( AuditParameters ));
|
||
|
||
AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
|
||
AuditParameters.AuditId = SE_AUDITID_AUDITS_DISCARDED;
|
||
AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
|
||
AuditParameters.ParameterCount = 0;
|
||
|
||
LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, LsapLocalSystemSid );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, NumberOfEventsDiscarded );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
PLUID LsaFilterPrivileges[] =
|
||
{
|
||
&ChangeNotifyPrivilege,
|
||
&AuditPrivilege,
|
||
&CreateTokenPrivilege,
|
||
&AssignPrimaryTokenPrivilege,
|
||
&BackupPrivilege,
|
||
&RestorePrivilege,
|
||
&DebugPrivilege,
|
||
NULL
|
||
};
|
||
|
||
|
||
VOID
|
||
LsapAdtAuditSpecialPrivileges(
|
||
PPRIVILEGE_SET Privileges,
|
||
LUID LogonId,
|
||
PSID UserSid
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Audits the assignment of special privileges at logon time.
|
||
|
||
Arguments:
|
||
|
||
Privileges - List of privileges being assigned.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
PPRIVILEGE_SET Buffer;
|
||
PLUID *FilterPrivilege = NULL;
|
||
ULONG i;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
|
||
if ( !LsapAdtEventsInformation.AuditingMode ) {
|
||
return;
|
||
}
|
||
|
||
if (!(LsapAdtEventsInformation.EventAuditingOptions[AuditCategoryPrivilegeUse] & POLICY_AUDIT_EVENT_SUCCESS)) {
|
||
return;
|
||
}
|
||
|
||
if ( (Privileges == NULL) || (Privileges->PrivilegeCount == 0) ) {
|
||
return;
|
||
}
|
||
|
||
//
|
||
// We can't need any more space than what's being passed in.
|
||
//
|
||
|
||
Buffer = (PPRIVILEGE_SET)LsapAllocateLsaHeap( LsapPrivilegeSetSize( Privileges ) );
|
||
|
||
if ( Buffer == NULL ) {
|
||
//
|
||
// ISSUE-2000/09/26-kumarp : call LsapAuditFailed
|
||
//
|
||
return;
|
||
}
|
||
|
||
Buffer->PrivilegeCount = 0;
|
||
|
||
//
|
||
// For each privilege in the privilege set, see if it's in the filter
|
||
// list.
|
||
//
|
||
|
||
for ( i=0; i<Privileges->PrivilegeCount; i++) {
|
||
|
||
FilterPrivilege = LsaFilterPrivileges;
|
||
|
||
do {
|
||
|
||
if ( RtlEqualLuid( &Privileges->Privilege[i].Luid, *FilterPrivilege )) {
|
||
|
||
Buffer->Privilege[Buffer->PrivilegeCount].Luid = **FilterPrivilege;
|
||
Buffer->PrivilegeCount++;
|
||
}
|
||
|
||
} while ( *++FilterPrivilege != NULL );
|
||
}
|
||
|
||
if ( Buffer->PrivilegeCount == 0 ) {
|
||
LsapFreeLsaHeap( Buffer );
|
||
return;
|
||
}
|
||
|
||
//
|
||
// We matched on at least one, generate an audit.
|
||
//
|
||
|
||
RtlZeroMemory ((PVOID) &AuditParameters, sizeof( AuditParameters ));
|
||
|
||
AuditParameters.CategoryId = SE_CATEGID_PRIVILEGE_USE;
|
||
AuditParameters.AuditId = SE_AUDITID_ASSIGN_SPECIAL_PRIV;
|
||
AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
|
||
AuditParameters.ParameterCount = 0;
|
||
|
||
LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, LogonId );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypePrivileges( AuditParameters, AuditParameters.ParameterCount, Buffer );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
LsapFreeLsaHeap( Buffer );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
VOID
|
||
LsapAdtAuditPackageLoad(
|
||
PUNICODE_STRING PackageFileName
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Audits the loading of an authentication package.
|
||
|
||
Arguments:
|
||
|
||
PackageFileName - The name of the package being loaded.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
||
NTSTATUS Status;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
|
||
if ( !LsapAdtEventsInformation.AuditingMode ) {
|
||
return;
|
||
}
|
||
|
||
if (!(LsapAdtEventsInformation.EventAuditingOptions[AuditCategorySystem] & POLICY_AUDIT_EVENT_SUCCESS)) {
|
||
return;
|
||
}
|
||
|
||
RtlZeroMemory (
|
||
(PVOID) &AuditParameters,
|
||
sizeof( AuditParameters )
|
||
);
|
||
|
||
AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
|
||
AuditParameters.AuditId = SE_AUDITID_AUTH_PACKAGE_LOAD;
|
||
AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
|
||
AuditParameters.ParameterCount = 0;
|
||
|
||
LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, LsapLocalSystemSid );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, PackageFileName );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
LsapAdtAuditLogonProcessRegistration(
|
||
IN PLSAP_AU_REGISTER_CONNECT_INFO_EX ConnectInfo
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Audits the registration of a logon process
|
||
|
||
Arguments:
|
||
|
||
ConnectInfo - Supplies the connection information for the new
|
||
logon process.
|
||
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
|
||
NTSTATUS Status;
|
||
ANSI_STRING AnsiString;
|
||
UNICODE_STRING Unicode;
|
||
PSZ LogonProcessNameBuffer;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
|
||
if ( !LsapAdtEventsInformation.AuditingMode ) {
|
||
return;
|
||
}
|
||
|
||
if (!(LsapAdtEventsInformation.EventAuditingOptions[AuditCategorySystem] & POLICY_AUDIT_EVENT_SUCCESS)) {
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Turn the name text in the ConnectInfo structure into
|
||
// something we can work with.
|
||
//
|
||
|
||
LogonProcessNameBuffer = (PSZ)LsapAllocateLsaHeap( ConnectInfo->LogonProcessNameLength+1 );
|
||
|
||
if ( LogonProcessNameBuffer == NULL ) {
|
||
|
||
return;
|
||
}
|
||
|
||
RtlCopyMemory(
|
||
LogonProcessNameBuffer,
|
||
ConnectInfo->LogonProcessName,
|
||
ConnectInfo->LogonProcessNameLength
|
||
);
|
||
|
||
LogonProcessNameBuffer[ConnectInfo->LogonProcessNameLength] = 0;
|
||
RtlInitAnsiString( &AnsiString, LogonProcessNameBuffer );
|
||
|
||
Status = RtlAnsiStringToUnicodeString( &Unicode, &AnsiString, TRUE );
|
||
|
||
if ( !NT_SUCCESS( Status )) {
|
||
|
||
//
|
||
// Must be out of memory, not much we can do here
|
||
//
|
||
|
||
LsapFreeLsaHeap( LogonProcessNameBuffer );
|
||
return;
|
||
}
|
||
|
||
RtlZeroMemory (
|
||
(PVOID) &AuditParameters,
|
||
sizeof( AuditParameters )
|
||
);
|
||
|
||
AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
|
||
AuditParameters.AuditId = SE_AUDITID_SYSTEM_LOGON_PROC_REGISTER;
|
||
AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
|
||
AuditParameters.ParameterCount = 0;
|
||
|
||
LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, LsapLocalSystemSid );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &Unicode );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
LsapFreeLsaHeap( LogonProcessNameBuffer );
|
||
RtlFreeUnicodeString( &Unicode );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
|
||
|
||
VOID
|
||
LsapAdtSystemRestart(
|
||
PLSARM_POLICY_AUDIT_EVENTS_INFO AuditEventsInfo
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function is called during LSA initialization to generate
|
||
a system restart event.
|
||
|
||
Arguments:
|
||
|
||
AuditEventsInfo - Auditing data.
|
||
|
||
|
||
Return Value:
|
||
|
||
NTSTATUS - Standard Nt Result Code.
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
|
||
|
||
if(!AuditEventsInfo->AuditingMode) {
|
||
|
||
return;
|
||
}
|
||
|
||
if (!((AuditEventsInfo->EventAuditingOptions)[AuditCategorySystem] & POLICY_AUDIT_EVENT_SUCCESS )) {
|
||
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Construct an audit parameters array
|
||
// for the restart event.
|
||
//
|
||
|
||
RtlZeroMemory (
|
||
(PVOID) &AuditParameters,
|
||
sizeof( AuditParameters )
|
||
);
|
||
|
||
AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
|
||
AuditParameters.AuditId = SE_AUDITID_SYSTEM_RESTART;
|
||
AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
|
||
AuditParameters.ParameterCount = 0;
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, LsapLocalSystemSid );
|
||
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
|
||
|
||
AuditParameters.ParameterCount++;
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
return;
|
||
}
|
||
|
||
|
||
VOID
|
||
LsapAdtAuditLogon(
|
||
IN USHORT EventCategory,
|
||
IN ULONG EventID,
|
||
IN USHORT EventType,
|
||
IN PUNICODE_STRING AccountName,
|
||
IN PUNICODE_STRING AuthenticatingAuthority,
|
||
IN PUNICODE_STRING Source,
|
||
IN PUNICODE_STRING PackageName,
|
||
IN SECURITY_LOGON_TYPE LogonType,
|
||
IN PSID UserSid,
|
||
IN LUID AuthenticationId,
|
||
IN PUNICODE_STRING WorkstationName,
|
||
IN NTSTATUS LogonStatus,
|
||
IN NTSTATUS SubStatus,
|
||
IN LPGUID LogonGuid OPTIONAL
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generates an audit of a logon event as appropriate.
|
||
|
||
Arguments:
|
||
|
||
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
|
||
{
|
||
NTSTATUS Status = STATUS_SUCCESS;
|
||
UNICODE_STRING SpareString;
|
||
UNICODE_STRING AuthenticationIdString = { 0 };
|
||
BOOLEAN FreeWhenDone = FALSE;
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
BOOLEAN AuditingSuccess;
|
||
BOOLEAN AuditingFailure;
|
||
PSID pSid;
|
||
PLSAP_LOGON_SESSION pLogonSession = NULL;
|
||
|
||
|
||
RtlInitUnicodeString( &SpareString, L"Security");
|
||
|
||
AuditingFailure = (EventType == EVENTLOG_AUDIT_FAILURE) && LsapAuditFailedLogons;
|
||
AuditingSuccess = (EventType == EVENTLOG_AUDIT_SUCCESS) && LsapAuditSuccessfulLogons;
|
||
|
||
//
|
||
// return quickly if auditing is not enabled
|
||
//
|
||
if ( !(AuditingFailure || AuditingSuccess) )
|
||
{
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Build an audit parameters structure.
|
||
//
|
||
|
||
RtlZeroMemory ( (PVOID) &AuditParameters, sizeof( AuditParameters ) );
|
||
|
||
AuditParameters.CategoryId = EventCategory;
|
||
AuditParameters.AuditId = EventID;
|
||
AuditParameters.Type = EventType;
|
||
AuditParameters.ParameterCount = 0;
|
||
|
||
//
|
||
// If this is a successful logon audit event and the caller did not
|
||
// supply a logon GUID, extract it from the logon session.
|
||
//
|
||
if ( AuditingSuccess && !LogonGuid &&
|
||
( EventType == EVENTLOG_AUDIT_SUCCESS ) )
|
||
{
|
||
pLogonSession = LsapLocateLogonSession( &AuthenticationId );
|
||
|
||
ASSERT( pLogonSession && L"LsapAdtAuditLogon: logon session not found" );
|
||
|
||
if ( pLogonSession )
|
||
{
|
||
LogonGuid = &pLogonSession->LogonGuid;
|
||
}
|
||
}
|
||
|
||
#if DBG
|
||
if ( AuditingSuccess )
|
||
{
|
||
DsysAssert( EventID != SE_AUDITID_DOMAIN_TRUST_INCONSISTENT );
|
||
}
|
||
#endif
|
||
//
|
||
// User Sid
|
||
//
|
||
|
||
pSid = AuditingSuccess ? UserSid : LsapLocalSystemSid;
|
||
|
||
LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, pSid );
|
||
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &SpareString );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Account name
|
||
//
|
||
|
||
if ( ARGUMENT_PRESENT( AccountName ) ) {
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, AccountName );
|
||
|
||
}
|
||
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Authenticating Authority (domain name)
|
||
//
|
||
|
||
if ( ARGUMENT_PRESENT( AuthenticatingAuthority ) ) {
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, AuthenticatingAuthority );
|
||
|
||
}
|
||
|
||
AuditParameters.ParameterCount++;
|
||
|
||
if ( AuditingSuccess ) {
|
||
|
||
//
|
||
// Logon Id (as a string)
|
||
//
|
||
|
||
Status = LsapAdtBuildLuidString(
|
||
&AuthenticationId,
|
||
&AuthenticationIdString,
|
||
&FreeWhenDone
|
||
);
|
||
|
||
if ( NT_SUCCESS( Status )) {
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &AuthenticationIdString );
|
||
|
||
} else {
|
||
|
||
goto Finish;
|
||
}
|
||
|
||
AuditParameters.ParameterCount++;
|
||
}
|
||
|
||
//
|
||
// Logon Type
|
||
//
|
||
|
||
LsapSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, LogonType );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Source
|
||
//
|
||
|
||
if ( ARGUMENT_PRESENT( Source )) {
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, Source );
|
||
|
||
} else {
|
||
|
||
//
|
||
// No need to do anything here, since an empty entry will turn
|
||
// into a '-' in the output
|
||
//
|
||
|
||
}
|
||
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Authentication Package
|
||
//
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, PackageName );
|
||
AuditParameters.ParameterCount++;
|
||
|
||
//
|
||
// Workstation Name
|
||
//
|
||
|
||
if ( ARGUMENT_PRESENT( WorkstationName )) {
|
||
|
||
LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, WorkstationName );
|
||
}
|
||
|
||
AuditParameters.ParameterCount++;
|
||
|
||
if ( EventID == SE_AUDITID_UNSUCCESSFUL_LOGON ) {
|
||
|
||
//
|
||
// we need to supply the logon status for this event,
|
||
// so that some information can be gleened from the log.
|
||
//
|
||
|
||
LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, LogonStatus );
|
||
AuditParameters.ParameterCount++;
|
||
LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, SubStatus );
|
||
AuditParameters.ParameterCount++;
|
||
}
|
||
|
||
//
|
||
// Logon GUID
|
||
//
|
||
|
||
if ( ARGUMENT_PRESENT( LogonGuid )) {
|
||
|
||
LsapSetParmTypeGuid( AuditParameters, AuditParameters.ParameterCount, LogonGuid );
|
||
AuditParameters.ParameterCount++;
|
||
}
|
||
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Finish:
|
||
if (!NT_SUCCESS(Status))
|
||
{
|
||
LsapAuditFailed( Status );
|
||
}
|
||
|
||
if ( FreeWhenDone ) {
|
||
LsapFreeLsaHeap( AuthenticationIdString.Buffer );
|
||
}
|
||
|
||
if ( pLogonSession != NULL )
|
||
{
|
||
LsapReleaseLogonSession( pLogonSession );
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
VOID
|
||
LsapAuditLogon(
|
||
IN NTSTATUS LogonStatus,
|
||
IN NTSTATUS LogonSubStatus,
|
||
IN PUNICODE_STRING AccountName,
|
||
IN PUNICODE_STRING AuthenticatingAuthority,
|
||
IN PUNICODE_STRING WorkstationName,
|
||
IN PSID UserSid, OPTIONAL
|
||
IN SECURITY_LOGON_TYPE LogonType,
|
||
IN PTOKEN_SOURCE TokenSource,
|
||
IN PLUID LogonId
|
||
)
|
||
/*++
|
||
|
||
Routine Description/Arguments/Return value
|
||
|
||
See header comment for LsapAuditLogonHelper
|
||
|
||
--*/
|
||
{
|
||
LsapAuditLogonHelper(
|
||
LogonStatus,
|
||
LogonSubStatus,
|
||
AccountName,
|
||
AuthenticatingAuthority,
|
||
WorkstationName,
|
||
UserSid,
|
||
LogonType,
|
||
TokenSource,
|
||
LogonId,
|
||
NULL // no logon guid
|
||
);
|
||
}
|
||
|
||
|
||
|
||
|
||
VOID
|
||
LsapAuditLogonHelper(
|
||
IN NTSTATUS LogonStatus,
|
||
IN NTSTATUS LogonSubStatus,
|
||
IN PUNICODE_STRING AccountName,
|
||
IN PUNICODE_STRING AuthenticatingAuthority,
|
||
IN PUNICODE_STRING WorkstationName,
|
||
IN PSID UserSid, OPTIONAL
|
||
IN SECURITY_LOGON_TYPE LogonType,
|
||
IN PTOKEN_SOURCE TokenSource,
|
||
IN PLUID LogonId,
|
||
IN LPGUID LogonGuid OPTIONAL
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Helper routine for security packages to generate a logon audit
|
||
|
||
Arguments:
|
||
LogonStatus - Status code for the logon.
|
||
|
||
LogonSubStatus - more detailed Status code for the logon.
|
||
|
||
AccountName - Name of principal attempting logon.
|
||
|
||
AuthenticatingAuthority - Authority validating the logon.
|
||
|
||
Workstation - Machine from which the logon was attempted. For a network
|
||
logon, this should be the client machine.
|
||
|
||
UserSid - Sid for the logged on account.
|
||
|
||
LogonType - Type of logon, such as Network, Interactive, Service, etc.
|
||
|
||
TokenSource - Source for the token.
|
||
|
||
LogonId - If the logon was successful, the logon ID for the logon session.
|
||
|
||
LogonGuid - globally unique ID for a logon. currently this is supported
|
||
only by the kerberos package.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
ANSI_STRING AnsiSourceContext;
|
||
CHAR AnsiBuffer[TOKEN_SOURCE_LENGTH + 2];
|
||
UNICODE_STRING UnicodeSourceContext;
|
||
WCHAR UnicodeBuffer[TOKEN_SOURCE_LENGTH + 2];
|
||
NTSTATUS Status;
|
||
USHORT EventType;
|
||
USHORT EventCategory;
|
||
ULONG EventID;
|
||
PLSAP_SECURITY_PACKAGE SecurityPackage;
|
||
ULONG_PTR PackageId;
|
||
|
||
PackageId = GetCurrentPackageId();
|
||
DsysAssertMsg( PackageId != SPMGR_ID, "LsapAuditLogon" );
|
||
|
||
SecurityPackage = SpmpLocatePackage( PackageId );
|
||
DsysAssertMsg( SecurityPackage != NULL, "LsapAuditLogon" );
|
||
|
||
|
||
//
|
||
// Audit the logon attempt. The event type and logged information
|
||
// will depend to some extent on the whether we failed and why.
|
||
//
|
||
|
||
//
|
||
// Turn the SourceContext into something we can
|
||
// work with.
|
||
//
|
||
|
||
AnsiSourceContext.Buffer = AnsiBuffer;
|
||
AnsiSourceContext.Length = TOKEN_SOURCE_LENGTH * sizeof( CHAR );
|
||
AnsiSourceContext.MaximumLength = (TOKEN_SOURCE_LENGTH + 2) * sizeof( CHAR );
|
||
|
||
UnicodeSourceContext.Buffer = UnicodeBuffer;
|
||
UnicodeSourceContext.MaximumLength = (TOKEN_SOURCE_LENGTH + 2) * sizeof( WCHAR );
|
||
|
||
RtlCopyMemory(
|
||
AnsiBuffer,
|
||
TokenSource->SourceName,
|
||
TOKEN_SOURCE_LENGTH * sizeof( CHAR )
|
||
);
|
||
|
||
Status = RtlAnsiStringToUnicodeString(
|
||
&UnicodeSourceContext,
|
||
&AnsiSourceContext,
|
||
FALSE
|
||
);
|
||
|
||
if ( NT_SUCCESS( Status )) {
|
||
|
||
UnicodeSourceContext.Length =
|
||
(USHORT) LsapSafeWcslen( UnicodeSourceContext.Buffer,
|
||
UnicodeSourceContext.MaximumLength );
|
||
|
||
} else {
|
||
|
||
UnicodeSourceContext.Buffer = NULL;
|
||
|
||
//
|
||
// we cannot fail the audit because of this but catch the
|
||
// internal clients who supply bad source contexts
|
||
//
|
||
DsysAssertMsg( FALSE, "LsapAuditLogon: could not convert AnsiSourceContext to unicode" );
|
||
}
|
||
|
||
//
|
||
// Assume the logon failed, reset if necessary.
|
||
//
|
||
|
||
EventCategory = SE_CATEGID_LOGON;
|
||
EventType = EVENTLOG_AUDIT_FAILURE;
|
||
|
||
|
||
switch ( LogonStatus )
|
||
{
|
||
case STATUS_SUCCESS:
|
||
{
|
||
//
|
||
// Use a separate event for network logons
|
||
//
|
||
|
||
if (( LogonType == Network ) ||
|
||
( LogonType == NetworkCleartext ))
|
||
{
|
||
EventID = SE_AUDITID_NETWORK_LOGON;
|
||
}
|
||
else
|
||
{
|
||
EventID = SE_AUDITID_SUCCESSFUL_LOGON;
|
||
}
|
||
|
||
EventType = EVENTLOG_AUDIT_SUCCESS;
|
||
break;
|
||
}
|
||
|
||
case STATUS_BAD_VALIDATION_CLASS:
|
||
EventID = SE_AUDITID_UNSUCCESSFUL_LOGON;
|
||
break;
|
||
|
||
case STATUS_ACCOUNT_EXPIRED:
|
||
EventID = SE_AUDITID_ACCOUNT_EXPIRED;
|
||
break;
|
||
|
||
case STATUS_NETLOGON_NOT_STARTED:
|
||
EventID = SE_AUDITID_NETLOGON_NOT_STARTED;
|
||
break;
|
||
|
||
case STATUS_ACCOUNT_LOCKED_OUT:
|
||
EventID = SE_AUDITID_ACCOUNT_LOCKED;
|
||
break;
|
||
|
||
case STATUS_LOGON_TYPE_NOT_GRANTED:
|
||
EventID = SE_AUDITID_LOGON_TYPE_RESTR;
|
||
break;
|
||
|
||
case STATUS_PASSWORD_MUST_CHANGE:
|
||
EventID = SE_AUDITID_PASSWORD_EXPIRED;
|
||
break;
|
||
|
||
|
||
case STATUS_ACCOUNT_RESTRICTION:
|
||
{
|
||
|
||
switch ( LogonSubStatus )
|
||
{
|
||
case STATUS_PASSWORD_EXPIRED:
|
||
EventID = SE_AUDITID_PASSWORD_EXPIRED;
|
||
break;
|
||
|
||
case STATUS_ACCOUNT_DISABLED:
|
||
EventID = SE_AUDITID_ACCOUNT_DISABLED;
|
||
break;
|
||
|
||
case STATUS_INVALID_LOGON_HOURS:
|
||
EventID = SE_AUDITID_ACCOUNT_TIME_RESTR;
|
||
break;
|
||
|
||
case STATUS_INVALID_WORKSTATION:
|
||
EventID = SE_AUDITID_WORKSTATION_RESTR;
|
||
break;
|
||
|
||
default:
|
||
EventID = SE_AUDITID_UNKNOWN_USER_OR_PWD;
|
||
break;
|
||
}
|
||
break;
|
||
}
|
||
|
||
case STATUS_LOGON_FAILURE:
|
||
{
|
||
if ( ( LogonSubStatus == STATUS_WRONG_PASSWORD ) ||
|
||
( LogonSubStatus == STATUS_NO_SUCH_USER ) )
|
||
{
|
||
EventID = SE_AUDITID_UNKNOWN_USER_OR_PWD;
|
||
|
||
}
|
||
else if ( LogonSubStatus == STATUS_DOMAIN_TRUST_INCONSISTENT )
|
||
{
|
||
EventID = SE_AUDITID_DOMAIN_TRUST_INCONSISTENT;
|
||
}
|
||
else
|
||
{
|
||
EventID = SE_AUDITID_UNSUCCESSFUL_LOGON;
|
||
}
|
||
break;
|
||
}
|
||
|
||
default:
|
||
EventID = SE_AUDITID_UNSUCCESSFUL_LOGON;
|
||
break;
|
||
}
|
||
|
||
LsapAdtAuditLogon( EventCategory,
|
||
EventID,
|
||
EventType,
|
||
AccountName,
|
||
AuthenticatingAuthority,
|
||
&UnicodeSourceContext,
|
||
&SecurityPackage->Name,
|
||
LogonType,
|
||
UserSid,
|
||
*LogonId,
|
||
WorkstationName,
|
||
LogonStatus,
|
||
LogonSubStatus,
|
||
LogonGuid
|
||
);
|
||
|
||
}
|
||
|
||
|
||
VOID
|
||
LsapAdtAuditLogoff(
|
||
PLSAP_LOGON_SESSION Session
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Generates a logoff audit. The caller is responsible for determining
|
||
if logoff auditing is enabled.
|
||
|
||
Arguments:
|
||
|
||
Session - Points to the logon session being removed.
|
||
|
||
Return Value:
|
||
|
||
None.
|
||
|
||
--*/
|
||
{
|
||
SE_ADT_PARAMETER_ARRAY AuditParameters;
|
||
NTSTATUS Status;
|
||
UNICODE_STRING usLogonId;
|
||
BOOLEAN fFreeLogonId=FALSE;
|
||
|
||
RtlZeroMemory ( &usLogonId, sizeof(UNICODE_STRING) );
|
||
|
||
//
|
||
// normally we would simply store the logon-id to be audited
|
||
// as SeAdtParmTypeLogonId. But in this case, the logon session
|
||
// will have gone away by the time we try to convert it
|
||
// to a string representation in LsapAdtDemarshallAuditInfo.
|
||
// using LsapGetLogonSessionAccountInfo.
|
||
//
|
||
// To avoid this, we pre-convert the logon-id here
|
||
//
|
||
|
||
Status = LsapAdtBuildLuidString( &Session->LogonId,
|
||
&usLogonId, &fFreeLogonId );
|
||
|
||
if ( !NT_SUCCESS(Status) )
|
||
{
|
||
goto Cleanup;
|
||
}
|
||
|
||
|
||
LsapAdtInitParametersArray(
|
||
&AuditParameters,
|
||
SE_CATEGID_LOGON,
|
||
SE_AUDITID_LOGOFF,
|
||
EVENTLOG_AUDIT_SUCCESS,
|
||
6, // there are 6 params to init
|
||
|
||
//
|
||
// User Sid
|
||
//
|
||
SeAdtParmTypeSid, Session->UserSid,
|
||
|
||
//
|
||
// Subsystem name (if available)
|
||
//
|
||
SeAdtParmTypeString, &LsapSubsystemName,
|
||
|
||
//
|
||
// User
|
||
//
|
||
SeAdtParmTypeString, &Session->AccountName,
|
||
|
||
//
|
||
// Domain
|
||
//
|
||
SeAdtParmTypeString, &Session->AuthorityName,
|
||
|
||
//
|
||
// LogonId
|
||
//
|
||
SeAdtParmTypeString, &usLogonId,
|
||
|
||
//
|
||
// Logon Type
|
||
//
|
||
SeAdtParmTypeUlong, Session->LogonType );
|
||
|
||
|
||
( VOID ) LsapAdtWriteLog( &AuditParameters, 0 );
|
||
|
||
Cleanup:
|
||
if (fFreeLogonId)
|
||
{
|
||
LsapFreeLsaHeap(usLogonId.Buffer);
|
||
}
|
||
}
|