312 lines
9.3 KiB
C
312 lines
9.3 KiB
C
/*++
|
|
|
|
Copyright (c) 1997-2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
safelog.c (SAFER Event Logging)
|
|
|
|
Abstract:
|
|
|
|
This module implements the internal WinSAFER APIs to write eventlog
|
|
messages. All of our message strings are defined in ntstatus.mc
|
|
and are physically located within ntdll.dll file.
|
|
|
|
Currently we are just reusing the previously existing event source
|
|
called "Application Popup", which already happens to use ntdll.dll
|
|
as its message resource library. Events of this source always go
|
|
into the "System Log".
|
|
|
|
Author:
|
|
|
|
Jeffrey Lawson (JLawson) - Apr 1999
|
|
|
|
Environment:
|
|
|
|
User mode only.
|
|
|
|
Exported Functions:
|
|
|
|
SaferRecordEventLogEntry
|
|
|
|
Revision History:
|
|
|
|
Created - Nov 2000
|
|
|
|
--*/
|
|
|
|
#include "pch.h"
|
|
#pragma hdrstop
|
|
#include <winsafer.h>
|
|
#include <winsaferp.h>
|
|
#include "saferp.h"
|
|
|
|
|
|
|
|
|
|
const static GUID guidTrustedCert = SAFER_GUID_RESULT_TRUSTED_CERT;
|
|
const static GUID guidDefaultRule = SAFER_GUID_RESULT_DEFAULT_LEVEL;
|
|
|
|
|
|
|
|
BOOL WINAPI
|
|
SaferpRecordEventLogEntryHelper(
|
|
IN NTSTATUS LogStatusCode,
|
|
IN LPCWSTR szTargetPath,
|
|
IN REFGUID refRuleGuid,
|
|
IN LPCWSTR szRulePath
|
|
)
|
|
{
|
|
NTSTATUS Status = STATUS_UNSUCCESSFUL;
|
|
WORD wNumStrings = 0;
|
|
LPWSTR lpszStrings[5];
|
|
HANDLE hEventSource;
|
|
UNICODE_STRING UnicodeGuid;
|
|
BYTE LocalBuffer[SECURITY_MAX_SID_SIZE + sizeof(TOKEN_USER)];
|
|
PSID pSid = NULL;
|
|
HANDLE hToken = NULL;
|
|
DWORD Ignore = 0;
|
|
|
|
//
|
|
// Open the effective token on the thead and get the token user. On any
|
|
// intermediate failure in this operation, we still dump the event to the
|
|
// event log, without the user sid information.
|
|
//
|
|
|
|
//
|
|
// Get the effective token on the thread.
|
|
//
|
|
|
|
Status = NtOpenThreadToken(
|
|
NtCurrentThread(),
|
|
TOKEN_QUERY,
|
|
TRUE,
|
|
&hToken);
|
|
|
|
//
|
|
// If the thread is not impersonating, get the process token.
|
|
//
|
|
|
|
if (Status == STATUS_NO_TOKEN) {
|
|
Status = NtOpenProcessToken(
|
|
NtCurrentProcess(),
|
|
TOKEN_QUERY,
|
|
&hToken);
|
|
}
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
//
|
|
// Get the User Sid.
|
|
//
|
|
|
|
Status = NtQueryInformationToken (
|
|
hToken,
|
|
TokenUser,
|
|
LocalBuffer,
|
|
sizeof(LocalBuffer),
|
|
&Ignore);
|
|
|
|
NtClose(hToken);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
|
|
//
|
|
// We have successfully computed who the user is. This is good.
|
|
//
|
|
|
|
pSid = (PSID) (((PTOKEN_USER) LocalBuffer)->User.Sid);
|
|
}
|
|
}
|
|
|
|
hEventSource = RegisterEventSourceW(NULL, L"Software Restriction Policy");
|
|
|
|
if (hEventSource != NULL) {
|
|
|
|
Status = STATUS_SUCCESS;
|
|
RtlInitEmptyUnicodeString(&UnicodeGuid, NULL, 0);
|
|
|
|
switch (LogStatusCode)
|
|
{
|
|
case STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT:
|
|
if (!ARGUMENT_PRESENT(szTargetPath)) {
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
lpszStrings[0] = (LPWSTR) szTargetPath;
|
|
wNumStrings = 1;
|
|
break;
|
|
|
|
case STATUS_ACCESS_DISABLED_BY_POLICY_OTHER:
|
|
if (!ARGUMENT_PRESENT(szTargetPath) ||
|
|
!ARGUMENT_PRESENT(refRuleGuid)) {
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
|
|
Status = RtlStringFromGUID(refRuleGuid, &UnicodeGuid);
|
|
if (NT_SUCCESS(Status)) {
|
|
ASSERT(UnicodeGuid.Buffer != NULL);
|
|
lpszStrings[0] = (LPWSTR) szTargetPath;
|
|
lpszStrings[1] = UnicodeGuid.Buffer;
|
|
wNumStrings = 2;
|
|
}
|
|
break;
|
|
|
|
case STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER:
|
|
if (!ARGUMENT_PRESENT(szTargetPath)) {
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
lpszStrings[0] = (LPWSTR) szTargetPath;
|
|
wNumStrings = 1;
|
|
break;
|
|
|
|
case STATUS_ACCESS_DISABLED_BY_POLICY_PATH:
|
|
if (!ARGUMENT_PRESENT(szTargetPath) ||
|
|
!ARGUMENT_PRESENT(refRuleGuid) ||
|
|
!ARGUMENT_PRESENT(szRulePath)) {
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
break;
|
|
}
|
|
Status = RtlStringFromGUID(refRuleGuid, &UnicodeGuid);
|
|
if (NT_SUCCESS(Status)) {
|
|
ASSERT(UnicodeGuid.Buffer != NULL);
|
|
lpszStrings[0] = (LPWSTR) szTargetPath;
|
|
lpszStrings[1] = UnicodeGuid.Buffer;
|
|
lpszStrings[2] = (LPWSTR) szRulePath;
|
|
wNumStrings = 3;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
Status = STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
ReportEventW(
|
|
hEventSource, // handle to event log
|
|
EVENTLOG_WARNING_TYPE, // event type
|
|
0, // event category
|
|
LogStatusCode, // event ID
|
|
pSid, // current user's SID
|
|
wNumStrings, // strings in lpszStrings
|
|
0, // no bytes of raw data
|
|
lpszStrings, // array of error strings
|
|
NULL); // no raw data
|
|
}
|
|
|
|
DeregisterEventSource(hEventSource);
|
|
|
|
if (UnicodeGuid.Buffer != NULL) {
|
|
RtlFreeUnicodeString(&UnicodeGuid);
|
|
}
|
|
}
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
return TRUE;
|
|
} else {
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
BOOL WINAPI
|
|
SaferRecordEventLogEntry(
|
|
IN SAFER_LEVEL_HANDLE hAuthzLevel,
|
|
IN LPCWSTR szTargetPath,
|
|
IN LPVOID lpReserved
|
|
)
|
|
{
|
|
PSAFER_IDENTIFICATION_HEADER pIdentCommon;
|
|
DWORD dwIdentBufferSize;
|
|
BOOL bResult;
|
|
|
|
|
|
//
|
|
// Allocate enough memory for the largest structure we can expect
|
|
// and then query the information about the identifier that matched.
|
|
//
|
|
dwIdentBufferSize = max(sizeof(SAFER_HASH_IDENTIFICATION),
|
|
sizeof(SAFER_PATHNAME_IDENTIFICATION));
|
|
pIdentCommon = (PSAFER_IDENTIFICATION_HEADER)
|
|
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwIdentBufferSize);
|
|
if (!pIdentCommon) {
|
|
return FALSE;
|
|
}
|
|
pIdentCommon->cbStructSize = sizeof(SAFER_IDENTIFICATION_HEADER);
|
|
if (!SaferGetLevelInformation(
|
|
hAuthzLevel,
|
|
SaferObjectSingleIdentification,
|
|
pIdentCommon,
|
|
dwIdentBufferSize,
|
|
&dwIdentBufferSize)) {
|
|
|
|
if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) {
|
|
|
|
HeapFree(GetProcessHeap(), 0, pIdentCommon);
|
|
pIdentCommon = (PSAFER_IDENTIFICATION_HEADER)
|
|
HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwIdentBufferSize);
|
|
if (!pIdentCommon) {
|
|
return FALSE;
|
|
}
|
|
pIdentCommon->cbStructSize = sizeof(SAFER_IDENTIFICATION_HEADER);
|
|
if (!SaferGetLevelInformation(
|
|
hAuthzLevel,
|
|
SaferObjectSingleIdentification,
|
|
pIdentCommon,
|
|
dwIdentBufferSize,
|
|
&dwIdentBufferSize)) {
|
|
bResult = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
bResult = FALSE;
|
|
goto Cleanup;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Look at the resulting information about the identifier.
|
|
//
|
|
if (IsEqualGUID(&pIdentCommon->IdentificationGuid, &guidTrustedCert))
|
|
{
|
|
bResult = SaferpRecordEventLogEntryHelper(
|
|
STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER,
|
|
szTargetPath, NULL, NULL);
|
|
}
|
|
else if (IsEqualGUID(&pIdentCommon->IdentificationGuid, &guidDefaultRule))
|
|
{
|
|
bResult = SaferpRecordEventLogEntryHelper(
|
|
STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT,
|
|
szTargetPath, NULL, NULL);
|
|
}
|
|
else if (pIdentCommon->dwIdentificationType == SaferIdentityTypeImageName)
|
|
{
|
|
PSAFER_PATHNAME_IDENTIFICATION pIdentPath =
|
|
(PSAFER_PATHNAME_IDENTIFICATION) pIdentCommon;
|
|
bResult = SaferpRecordEventLogEntryHelper(
|
|
STATUS_ACCESS_DISABLED_BY_POLICY_PATH,
|
|
szTargetPath, &pIdentCommon->IdentificationGuid,
|
|
pIdentPath->ImageName);
|
|
}
|
|
else
|
|
{
|
|
bResult = SaferpRecordEventLogEntryHelper(
|
|
STATUS_ACCESS_DISABLED_BY_POLICY_OTHER,
|
|
szTargetPath, &pIdentCommon->IdentificationGuid,
|
|
NULL);
|
|
}
|
|
|
|
Cleanup:
|
|
HeapFree(GetProcessHeap(), 0, pIdentCommon);
|
|
|
|
return bResult;
|
|
}
|
|
|