Windows2003-3790/termsrv/notify/audit.c

492 lines
16 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;
}