2025-04-27 07:49:33 -04:00

3293 lines
80 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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);
}
}