492 lines
15 KiB
C
492 lines
15 KiB
C
|
/*******************************************************************************
|
||
|
* AUDIT.C
|
||
|
*
|
||
|
* This module contains the routines for logging audit events
|
||
|
*
|
||
|
* Copyright Citrix Systems Inc. 1995
|
||
|
* Copyright (C) 1997-1999 Microsoft Corp.
|
||
|
*
|
||
|
* Author: Thanh Luu
|
||
|
*******************************************************************************/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
#pragma hdrstop
|
||
|
#include <msaudite.h>
|
||
|
|
||
|
|
||
|
HANDLE AuditLogHandle = NULL;
|
||
|
//Authz Changes
|
||
|
AUTHZ_RESOURCE_MANAGER_HANDLE hRM = NULL;
|
||
|
//END Authz Changes
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
AdtBuildLuidString(
|
||
|
IN PLUID Value,
|
||
|
OUT PUNICODE_STRING ResultantString
|
||
|
);
|
||
|
VOID
|
||
|
AuditEvent( PGLOBALS pGlobals, ULONG EventId );
|
||
|
|
||
|
BOOL
|
||
|
AuditingEnabled ();
|
||
|
|
||
|
NTSTATUS
|
||
|
AuthzReportEventW( IN PAUTHZ_AUDIT_EVENT_TYPE_HANDLE pHAET,
|
||
|
IN DWORD Flags,
|
||
|
IN ULONG EventId,
|
||
|
IN PSID pUserID,
|
||
|
IN USHORT NumStrings,
|
||
|
IN ULONG DataSize OPTIONAL, //Future - DO NOT USE
|
||
|
IN PWSTR* Strings,
|
||
|
IN PVOID Data OPTIONAL //Future - DO NOT USE
|
||
|
);
|
||
|
|
||
|
|
||
|
BOOL AuthzInit( IN DWORD Flags,
|
||
|
IN USHORT CategoryID,
|
||
|
IN USHORT AuditID,
|
||
|
IN USHORT ParameterCount,
|
||
|
OUT PAUTHZ_AUDIT_EVENT_TYPE_HANDLE phAuditEventType
|
||
|
);
|
||
|
|
||
|
|
||
|
NTSTATUS
|
||
|
AdtBuildLuidString(
|
||
|
IN PLUID Value,
|
||
|
OUT PUNICODE_STRING ResultantString
|
||
|
)
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This function builds a unicode string representing the passed LUID.
|
||
|
|
||
|
The resultant string will be formatted as follows:
|
||
|
|
||
|
(0x00005678,0x12340000)
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
Value - The value to be transformed to printable format (Unicode string).
|
||
|
|
||
|
ResultantString - Points to the unicode string header. The body of this
|
||
|
unicode string will be set to point to the resultant output value
|
||
|
if successful. Otherwise, the Buffer field of this parameter
|
||
|
will be set to NULL.
|
||
|
|
||
|
FreeWhenDone - If TRUE, indicates that the body of the ResultantString
|
||
|
must be freed to process heap when no longer needed.
|
||
|
|
||
|
|
||
|
Return Values:
|
||
|
|
||
|
STATUS_NO_MEMORY - indicates memory could not be allocated
|
||
|
for the string body.
|
||
|
|
||
|
All other Result Codes are generated by called routines.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
{
|
||
|
NTSTATUS Status;
|
||
|
UNICODE_STRING IntegerString;
|
||
|
|
||
|
ULONG Buffer[(16*sizeof(WCHAR))/sizeof(ULONG)];
|
||
|
|
||
|
|
||
|
IntegerString.Buffer = (PWCHAR)&Buffer[0];
|
||
|
IntegerString.MaximumLength = 16*sizeof(WCHAR);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Length (in WCHARS) is 3 for (0x
|
||
|
// 10 for 1st hex number
|
||
|
// 3 for ,0x
|
||
|
// 10 for 2nd hex number
|
||
|
// 1 for )
|
||
|
// 1 for null termination
|
||
|
//
|
||
|
|
||
|
ResultantString->Length = 0;
|
||
|
ResultantString->MaximumLength = 28 * sizeof(WCHAR);
|
||
|
|
||
|
ResultantString->Buffer = RtlAllocateHeap( RtlProcessHeap(), 0,
|
||
|
ResultantString->MaximumLength);
|
||
|
if (ResultantString->Buffer == NULL) {
|
||
|
return(STATUS_NO_MEMORY);
|
||
|
}
|
||
|
|
||
|
Status = RtlAppendUnicodeToString( ResultantString, L"(0x" );
|
||
|
Status = RtlIntegerToUnicodeString( Value->HighPart, 16, &IntegerString );
|
||
|
Status = RtlAppendUnicodeToString( ResultantString, IntegerString.Buffer );
|
||
|
|
||
|
Status = RtlAppendUnicodeToString( ResultantString, L",0x" );
|
||
|
Status = RtlIntegerToUnicodeString( Value->LowPart, 16, &IntegerString );
|
||
|
Status = RtlAppendUnicodeToString( ResultantString, IntegerString.Buffer );
|
||
|
|
||
|
Status = RtlAppendUnicodeToString( ResultantString, L")" );
|
||
|
|
||
|
return(STATUS_SUCCESS);
|
||
|
}
|
||
|
|
||
|
|
||
|
VOID
|
||
|
AuditEvent( PGLOBALS pGlobals, ULONG EventId )
|
||
|
{
|
||
|
NTSTATUS Status;
|
||
|
WINSTATIONNAME WinStationName;
|
||
|
USHORT StringIndex = 0;
|
||
|
WINSTATIONCLIENT ClientData;
|
||
|
ULONG Length;
|
||
|
BOOL bResult = FALSE;
|
||
|
UNICODE_STRING LuidString;
|
||
|
PWSTR StringPointerArray[6];
|
||
|
TOKEN_STATISTICS TokenInformation;
|
||
|
ULONG ReturnLength;
|
||
|
BOOLEAN WasEnabled;
|
||
|
LUID LogonId = {0,0};
|
||
|
AUTHZ_AUDIT_EVENT_TYPE_HANDLE hAET = NULL;
|
||
|
|
||
|
if (!AuditingEnabled() || pGlobals->AuditLogFull)
|
||
|
return;
|
||
|
|
||
|
//
|
||
|
//AUTHZ Changes
|
||
|
//
|
||
|
if( !AuthzInit( 0, SE_CATEGID_LOGON, (USHORT)EventId, 6, &hAET ))
|
||
|
goto badAuthzInit;
|
||
|
|
||
|
StringPointerArray[StringIndex] = pGlobals->UserName ;
|
||
|
StringIndex++;
|
||
|
|
||
|
StringPointerArray[StringIndex] = pGlobals->Domain;
|
||
|
StringIndex++;
|
||
|
|
||
|
Status = AdtBuildLuidString( &pGlobals->LogonId, &LuidString );
|
||
|
StringPointerArray[StringIndex] = LuidString.Buffer;
|
||
|
StringIndex++;
|
||
|
|
||
|
WinStationNameFromLogonId( SERVERNAME_CURRENT, LOGONID_CURRENT, WinStationName );
|
||
|
StringPointerArray[StringIndex] = WinStationName;
|
||
|
StringIndex++;
|
||
|
|
||
|
bResult = WinStationQueryInformation( SERVERNAME_CURRENT,
|
||
|
LOGONID_CURRENT,
|
||
|
WinStationClient,
|
||
|
&ClientData,
|
||
|
sizeof(ClientData),
|
||
|
&Length );
|
||
|
|
||
|
if ( bResult )
|
||
|
StringPointerArray[StringIndex] = ClientData.ClientName;
|
||
|
else
|
||
|
StringPointerArray[StringIndex = L"Unknown";
|
||
|
StringIndex++;
|
||
|
|
||
|
if ( bResult )
|
||
|
StringPointerArray[StringIndex] = ClientData.ClientAddress;
|
||
|
else
|
||
|
StringPointerArray[StringIndex] = L"Unknown";
|
||
|
StringIndex++;
|
||
|
|
||
|
//Authz Changes
|
||
|
|
||
|
Status = AuthzReportEventW( &hAET,
|
||
|
APF_AuditSuccess,
|
||
|
EventId,
|
||
|
NULL,
|
||
|
StringIndex,
|
||
|
0,
|
||
|
StringPointerArray,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
//end authz changes
|
||
|
|
||
|
|
||
|
if ( !NT_SUCCESS(Status))
|
||
|
DBGPRINT(("Termsrv - failed to report event \n" ));
|
||
|
|
||
|
badAuthzInit:
|
||
|
if( hAET != NULL )
|
||
|
AuthziFreeAuditEventType( hAET );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
/***************************************************************************\
|
||
|
* AuditingEnabled
|
||
|
*
|
||
|
* Purpose : Check auditing via LSA.
|
||
|
*
|
||
|
* Returns: TRUE on success, FALSE on failure
|
||
|
*
|
||
|
* History:
|
||
|
* 5-6-92 DaveHart Created.
|
||
|
\***************************************************************************/
|
||
|
|
||
|
BOOL
|
||
|
AuditingEnabled()
|
||
|
{
|
||
|
NTSTATUS Status, IgnoreStatus;
|
||
|
PPOLICY_AUDIT_EVENTS_INFO AuditInfo;
|
||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||
|
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
|
||
|
LSA_HANDLE PolicyHandle;
|
||
|
|
||
|
//
|
||
|
// Set up the Security Quality Of Service for connecting to the
|
||
|
// LSA policy object.
|
||
|
//
|
||
|
|
||
|
SecurityQualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
|
||
|
SecurityQualityOfService.ImpersonationLevel = SecurityImpersonation;
|
||
|
SecurityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
|
||
|
SecurityQualityOfService.EffectiveOnly = FALSE;
|
||
|
|
||
|
//
|
||
|
// Set up the object attributes to open the Lsa policy object
|
||
|
//
|
||
|
|
||
|
InitializeObjectAttributes(
|
||
|
&ObjectAttributes,
|
||
|
NULL,
|
||
|
0L,
|
||
|
NULL,
|
||
|
NULL
|
||
|
);
|
||
|
ObjectAttributes.SecurityQualityOfService = &SecurityQualityOfService;
|
||
|
|
||
|
//
|
||
|
// Open the local LSA policy object
|
||
|
//
|
||
|
|
||
|
Status = LsaOpenPolicy(
|
||
|
NULL,
|
||
|
&ObjectAttributes,
|
||
|
POLICY_VIEW_AUDIT_INFORMATION | POLICY_SET_AUDIT_REQUIREMENTS,
|
||
|
&PolicyHandle
|
||
|
);
|
||
|
if (!NT_SUCCESS(Status)) {
|
||
|
DebugLog((DEB_ERROR, "Failed to open LsaPolicyObject Status = 0x%lx", Status));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
Status = LsaQueryInformationPolicy(
|
||
|
PolicyHandle,
|
||
|
PolicyAuditEventsInformation,
|
||
|
(PVOID *)&AuditInfo
|
||
|
);
|
||
|
IgnoreStatus = LsaClose(PolicyHandle);
|
||
|
ASSERT(NT_SUCCESS(IgnoreStatus));
|
||
|
|
||
|
if (!NT_SUCCESS(Status)) {
|
||
|
DebugLog((DEB_ERROR, "Failed to query audit event info Status = 0x%lx", Status));
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
return (AuditInfo->AuditingMode &&
|
||
|
((AuditInfo->EventAuditingOptions)[AuditCategoryLogon] &
|
||
|
POLICY_AUDIT_EVENT_SUCCESS));
|
||
|
}
|
||
|
|
||
|
|
||
|
/*************************************************************
|
||
|
* AuthzInit Purpose : Initialize authz for logging an event to the security log
|
||
|
*Flags - unused
|
||
|
*Category Id - Security Category to which this event belongs
|
||
|
*Audit Id - An id for the event
|
||
|
*PArameter count - Number of parameters that will be passed to the logging function later
|
||
|
****************************************************************/
|
||
|
|
||
|
BOOL AuthzInit( IN DWORD Flags,
|
||
|
IN USHORT CategoryID,
|
||
|
IN USHORT AuditID,
|
||
|
IN USHORT ParameterCount,
|
||
|
OUT PAUTHZ_AUDIT_EVENT_TYPE_HANDLE phAuditEventType
|
||
|
)
|
||
|
{
|
||
|
BOOL fAuthzInit = TRUE;
|
||
|
|
||
|
if( NULL == phAuditEventType )
|
||
|
goto badAuthzInit;
|
||
|
|
||
|
if( NULL == hRM )
|
||
|
{
|
||
|
fAuthzInit = AuthzInitializeResourceManager( 0,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
NULL,
|
||
|
L"Terminal Server",
|
||
|
&hRM
|
||
|
);
|
||
|
|
||
|
if ( !fAuthzInit )
|
||
|
{
|
||
|
DBGPRINT(("TERMSRV: AuditEvent: AuthzInitializeResourceManager failed with %d\n", GetLastError()));
|
||
|
goto badAuthzInit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fAuthzInit = AuthziInitializeAuditEventType( Flags,
|
||
|
CategoryID,
|
||
|
AuditID,
|
||
|
ParameterCount,
|
||
|
phAuditEventType
|
||
|
);
|
||
|
|
||
|
if ( !fAuthzInit )
|
||
|
{
|
||
|
DBGPRINT(("TERMSRV: AuditEvent: AuthziInitializeAuditEventType failed with %d\n", GetLastError()));
|
||
|
goto badAuthzInit;
|
||
|
}
|
||
|
|
||
|
badAuthzInit:
|
||
|
if( !fAuthzInit )
|
||
|
{
|
||
|
if( NULL != hRM )
|
||
|
{
|
||
|
if( !AuthzFreeResourceManager( hRM ))
|
||
|
DBGPRINT(("TERMSRV: AuditEvent: AuthzFreeResourceManager failed with %d\n", GetLastError()));
|
||
|
hRM = NULL;
|
||
|
}
|
||
|
if( NULL != *phAuditEventType )
|
||
|
{
|
||
|
if( !AuthziFreeAuditEventType( *phAuditEventType ))
|
||
|
DBGPRINT(("TERMSRV: AuditEvent: AuthziFreeAuditEventType failed with %d\n", GetLastError()));
|
||
|
*phAuditEventType = NULL;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// if( fAuthzInit )
|
||
|
// DBGPRINT(("TERMSRV: Successfully initialized authz = %d\n", AuditID));
|
||
|
return fAuthzInit;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*********************************************************
|
||
|
* Purpose : Log an Event to the security log
|
||
|
* In pHAET
|
||
|
* Audit Event type obtained from a call to AuthzInit() above
|
||
|
* In Flags
|
||
|
* APF_AuditSuccess or others as listed in the header file
|
||
|
* pUserSID - Unused
|
||
|
* NumStrings - Number of strings contained within "Strings"
|
||
|
* DataSize - unused
|
||
|
* Strings- Pointer to a sequence of unicode strings
|
||
|
* Data - unused
|
||
|
*
|
||
|
**********************************************************/
|
||
|
NTSTATUS
|
||
|
AuthzReportEventW( IN PAUTHZ_AUDIT_EVENT_TYPE_HANDLE pHAET,
|
||
|
IN DWORD Flags,
|
||
|
IN ULONG EventId,
|
||
|
IN PSID pUserSID,
|
||
|
IN USHORT NumStrings,
|
||
|
IN ULONG DataSize OPTIONAL, //Future - DO NOT USE
|
||
|
IN PWSTR* Strings,
|
||
|
IN PVOID Data OPTIONAL //Future - DO NOT USE
|
||
|
)
|
||
|
{
|
||
|
NTSTATUS status = STATUS_ACCESS_DENIED;
|
||
|
AUTHZ_AUDIT_EVENT_HANDLE hAE = NULL;
|
||
|
BOOL fSuccess = FALSE;
|
||
|
PAUDIT_PARAMS pParams = NULL;
|
||
|
|
||
|
if( NULL == hRM || NULL == pHAET || *pHAET == NULL )
|
||
|
return status;
|
||
|
|
||
|
fSuccess = AuthziAllocateAuditParams( &pParams, NumStrings );
|
||
|
|
||
|
if ( !fSuccess )
|
||
|
{
|
||
|
DBGPRINT(("TERMSRV: AuditEvent: AuthzAllocateAuditParams failed with %d\n", GetLastError()));
|
||
|
goto BadAuditEvent;
|
||
|
}
|
||
|
|
||
|
|
||
|
if( 6 == NumStrings )
|
||
|
{
|
||
|
fSuccess = AuthziInitializeAuditParamsWithRM( Flags,
|
||
|
hRM,
|
||
|
NumStrings,
|
||
|
pParams,
|
||
|
APT_String, Strings[0],
|
||
|
APT_String, Strings[1],
|
||
|
APT_String, Strings[2],
|
||
|
APT_String, Strings[3],
|
||
|
APT_String, Strings[4],
|
||
|
APT_String, Strings[5]
|
||
|
);
|
||
|
}
|
||
|
else if( 0 == NumStrings )
|
||
|
{
|
||
|
fSuccess = AuthziInitializeAuditParamsWithRM( Flags,
|
||
|
hRM,
|
||
|
NumStrings,
|
||
|
pParams
|
||
|
);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//we don't support anything else
|
||
|
fSuccess = FALSE;
|
||
|
DBGPRINT(("TERMSRV: AuditEvent: unsupported audit type \n"));
|
||
|
goto BadAuditEvent;
|
||
|
}
|
||
|
|
||
|
if ( !fSuccess )
|
||
|
{
|
||
|
DBGPRINT(("TERMSRV: AuditEvent: AuthziInitializeAuditParamsWithRM failed with %d\n", GetLastError()));
|
||
|
goto BadAuditEvent;
|
||
|
}
|
||
|
|
||
|
fSuccess = AuthziInitializeAuditEvent( 0,
|
||
|
hRM,
|
||
|
*pHAET,
|
||
|
pParams,
|
||
|
NULL,
|
||
|
INFINITE,
|
||
|
L"",
|
||
|
L"",
|
||
|
L"",
|
||
|
L"",
|
||
|
&hAE
|
||
|
);
|
||
|
|
||
|
if ( !fSuccess )
|
||
|
{
|
||
|
DBGPRINT(("TERMSRV: AuditEvent: AuthziInitializeAuditEvent failed with %d\n", GetLastError()));
|
||
|
goto BadAuditEvent;
|
||
|
}
|
||
|
|
||
|
fSuccess = AuthziLogAuditEvent( 0,
|
||
|
hAE,
|
||
|
NULL
|
||
|
);
|
||
|
|
||
|
if ( !fSuccess )
|
||
|
{
|
||
|
DBGPRINT(("TERMSRV: AuditEvent: AuthziLogAuditEvent failed with %d\n", GetLastError()));
|
||
|
goto BadAuditEvent;
|
||
|
}
|
||
|
|
||
|
BadAuditEvent:
|
||
|
|
||
|
if( hAE )
|
||
|
AuthzFreeAuditEvent( hAE );
|
||
|
|
||
|
if( pParams )
|
||
|
AuthziFreeAuditParams( pParams );
|
||
|
|
||
|
if( fSuccess )
|
||
|
status = STATUS_SUCCESS;
|
||
|
|
||
|
//if( fSuccess )
|
||
|
// DBGPRINT(("TERMSRV: Successfully audited event with authz= %d\n", EventId));
|
||
|
return status;
|
||
|
}
|