You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
815 lines
19 KiB
815 lines
19 KiB
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
|
//
|
|
// File: events.cxx
|
|
//
|
|
// Contents:
|
|
//
|
|
// Classes:
|
|
//
|
|
// Functions:
|
|
//
|
|
// History: 1-03-95 RichardW Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "kdcsvr.hxx"
|
|
#include <netlib.h>
|
|
extern "C" {
|
|
#include <lmserver.h>
|
|
#include <srvann.h>
|
|
}
|
|
|
|
HANDLE hEventLog = (HANDLE)NULL;
|
|
DWORD LoggingLevel = (1 << EVENTLOG_ERROR_TYPE) | (1 << EVENTLOG_WARNING_TYPE);
|
|
WCHAR EventSourceName[] = TEXT("KDC");
|
|
|
|
#define MAX_EVENT_STRINGS 8
|
|
#define MAX_ETYPE_LONG 999
|
|
#define MIN_ETYPE_LONG -999
|
|
#define MAX_ETYPE_STRING 16 // 4wchar + , + 2 space
|
|
#define WSZ_NO_KEYS L"< >"
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: InitializeEvents
|
|
//
|
|
// Synopsis: Connects to event log service
|
|
//
|
|
// Arguments: (none)
|
|
//
|
|
// History: 1-03-95 RichardW Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL
|
|
InitializeEvents(void)
|
|
{
|
|
TRACE(KDC, InitializeEvents, DEB_FUNCTION);
|
|
//
|
|
// Interval with which we'll log the same event twice
|
|
//
|
|
|
|
#define KDC_EVENT_LIFETIME (60*60*1000)
|
|
|
|
hEventLog = NetpEventlogOpen(EventSourceName, KDC_EVENT_LIFETIME);
|
|
if (hEventLog)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
|
|
DebugLog((DEB_ERROR, "Could not open event log, error %d\n", GetLastError()));
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: ReportServiceEvent
|
|
//
|
|
// Synopsis: Reports an event to the event log
|
|
//
|
|
// Arguments: [EventType] -- EventType (ERROR, WARNING, etc.)
|
|
// [EventId] -- Event ID
|
|
// [SizeOfRawData] -- Size of raw data
|
|
// [RawData] -- Raw data
|
|
// [NumberOfStrings] -- number of strings
|
|
// ... -- PWSTRs to string data
|
|
//
|
|
// History: 1-03-95 RichardW Created
|
|
//
|
|
// Notes:
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
DWORD
|
|
ReportServiceEvent(
|
|
IN WORD EventType,
|
|
IN DWORD EventId,
|
|
IN DWORD SizeOfRawData,
|
|
IN PVOID RawData,
|
|
IN DWORD NumberOfStrings,
|
|
...
|
|
)
|
|
{
|
|
TRACE(KDC, ReportServiceEvent, DEB_FUNCTION);
|
|
|
|
va_list arglist;
|
|
ULONG i;
|
|
PWSTR Strings[ MAX_EVENT_STRINGS ];
|
|
DWORD rv;
|
|
|
|
if (!hEventLog)
|
|
{
|
|
DebugLog((DEB_ERROR, "Cannot log event, no handle!\n"));
|
|
return((DWORD)-1);
|
|
}
|
|
|
|
//
|
|
// Look at the strings, if they were provided
|
|
//
|
|
va_start( arglist, NumberOfStrings );
|
|
|
|
if (NumberOfStrings > MAX_EVENT_STRINGS) {
|
|
|
|
NumberOfStrings = MAX_EVENT_STRINGS;
|
|
}
|
|
|
|
for (i = 0; i<NumberOfStrings; i++) {
|
|
|
|
Strings[ i ] = va_arg( arglist, PWSTR );
|
|
}
|
|
|
|
//
|
|
// Report the event to the eventlog service
|
|
//
|
|
|
|
if ((rv = NetpEventlogWrite(
|
|
hEventLog,
|
|
EventId,
|
|
EventType,
|
|
(PBYTE) RawData,
|
|
SizeOfRawData,
|
|
(LPWSTR *) Strings,
|
|
NumberOfStrings
|
|
)) != ERROR_SUCCESS)
|
|
{
|
|
DebugLog((DEB_ERROR, "NetpEventlogWrite( 0x%x ) failed - %u\n", EventId, rv ));
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
BOOL
|
|
ShutdownEvents(void)
|
|
{
|
|
TRACE(KDC, ShutdownEvents, DEB_FUNCTION);
|
|
|
|
NetpEventlogClose(hEventLog);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
NTSTATUS
|
|
KdcBuildEtypeStringFromStoredCredential(
|
|
IN OPTIONAL PKERB_STORED_CREDENTIAL Cred,
|
|
IN OUT PWSTR* EtypeString
|
|
)
|
|
{
|
|
ULONG BuffSize;
|
|
PWSTR Ret = NULL;
|
|
SIZE_T Len = 0;
|
|
WCHAR Buff[12];
|
|
|
|
*EtypeString = NULL;
|
|
|
|
|
|
if (Cred == NULL
|
|
|| ((Cred->CredentialCount + Cred->OldCredentialCount) == 0))
|
|
{
|
|
BuffSize = (ULONG) sizeof(WCHAR) * (ULONG) (wcslen(WSZ_NO_KEYS)+1);
|
|
*EtypeString = (LPWSTR)MIDL_user_allocate(BuffSize);
|
|
|
|
if (NULL == *EtypeString)
|
|
{
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
wcscpy(*EtypeString, WSZ_NO_KEYS);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
// Guess maximum buffer... Etypes are 4 chars at most
|
|
BuffSize = ((Cred->CredentialCount + Cred->OldCredentialCount ) * MAX_ETYPE_STRING);
|
|
Ret = (LPWSTR)MIDL_user_allocate(BuffSize + sizeof(WCHAR));
|
|
if (NULL == Ret)
|
|
{
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
for (LONG Index = 0; Index < (Cred->CredentialCount + Cred->OldCredentialCount ); Index++)
|
|
{
|
|
if (Cred->Credentials[Index].Key.keytype > MAX_ETYPE_LONG ||
|
|
Cred->Credentials[Index].Key.keytype < MIN_ETYPE_LONG)
|
|
{
|
|
DebugLog((DEB_ERROR, "Keytype too large for string conversion\n"));
|
|
DsysAssert(FALSE);
|
|
}
|
|
else
|
|
{
|
|
_itow(Cred->Credentials[Index].Key.keytype, Buff, 10);
|
|
wcscat(Ret, Buff);
|
|
wcscat(Ret, L" ");
|
|
}
|
|
}
|
|
|
|
//
|
|
// stripping out trailing white spaces
|
|
//
|
|
|
|
Len = wcslen(Ret);
|
|
|
|
while (Len && iswspace(Ret[Len - 1]))
|
|
{
|
|
Ret[(Len--) - 1] = L'\0';
|
|
}
|
|
|
|
*EtypeString = Ret;
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
NTSTATUS
|
|
KdcBuildEtypeStringFromCryptList(
|
|
IN OPTIONAL PKERB_CRYPT_LIST CryptList,
|
|
IN OUT LPWSTR * EtypeString
|
|
)
|
|
{
|
|
SIZE_T Len = 0;
|
|
ULONG BuffSize = 0;
|
|
PWSTR Ret = NULL;
|
|
WCHAR Buff[30];
|
|
|
|
PKERB_CRYPT_LIST ListPointer = CryptList;
|
|
|
|
*EtypeString = NULL;
|
|
|
|
|
|
if (CryptList == NULL)
|
|
{
|
|
BuffSize = (ULONG) sizeof(WCHAR) * (ULONG) (wcslen(WSZ_NO_KEYS)+1);
|
|
*EtypeString = (LPWSTR)MIDL_user_allocate(BuffSize);
|
|
|
|
if (NULL == *EtypeString)
|
|
{
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
wcscpy(*EtypeString, WSZ_NO_KEYS);
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
while (TRUE)
|
|
{
|
|
if (ListPointer->value > MAX_ETYPE_LONG || ListPointer->value < MIN_ETYPE_LONG)
|
|
{
|
|
DebugLog((DEB_ERROR, "Maximum etype exceeded\n"));
|
|
return STATUS_INVALID_PARAMETER;
|
|
}
|
|
|
|
BuffSize += MAX_ETYPE_STRING;
|
|
if (NULL == ListPointer->next)
|
|
{
|
|
break;
|
|
}
|
|
ListPointer = ListPointer->next;
|
|
|
|
}
|
|
|
|
Ret = (LPWSTR) MIDL_user_allocate(BuffSize + sizeof(WCHAR));
|
|
if (NULL == Ret)
|
|
{
|
|
return STATUS_INSUFFICIENT_RESOURCES;
|
|
}
|
|
|
|
while (TRUE)
|
|
{
|
|
_itow(CryptList->value, Buff, 10);
|
|
wcscat(Ret, Buff);
|
|
wcscat(Ret, L" ");
|
|
if (NULL == CryptList->next)
|
|
{
|
|
break;
|
|
}
|
|
|
|
CryptList = CryptList->next;
|
|
|
|
}
|
|
|
|
//
|
|
// stripping out trailing white spaces
|
|
//
|
|
|
|
Len = wcslen(Ret);
|
|
|
|
while (Len && iswspace(Ret[Len - 1]))
|
|
{
|
|
Ret[(Len--) - 1] = L'\0';
|
|
}
|
|
|
|
*EtypeString = Ret;
|
|
|
|
return STATUS_SUCCESS;
|
|
}
|
|
|
|
void
|
|
KdcReportKeyError(
|
|
IN PUNICODE_STRING AccountName,
|
|
IN OPTIONAL PUNICODE_STRING ServerName,
|
|
IN ULONG DescriptionID, // uniquely descibe the location of key error
|
|
IN ULONG EventId,
|
|
IN OPTIONAL PKERB_CRYPT_LIST RequestEtypes,
|
|
IN PKDC_TICKET_INFO AccountTicketInfo
|
|
)
|
|
{
|
|
ULONG NumberOfStrings;
|
|
NTSTATUS Status;
|
|
PWSTR Strings[ MAX_EVENT_STRINGS ];
|
|
PWSTR RequestEtypeString = NULL;
|
|
PWSTR StoredEtypeString = NULL;
|
|
DWORD rv;
|
|
ULONG KdcEtypes[KERB_MAX_CRYPTO_SYSTEMS];
|
|
ULONG KdcEtypeCount = 0;
|
|
BOOL IsEtypeSupported = FALSE;
|
|
WCHAR Description[16] = {0};
|
|
|
|
if (!hEventLog)
|
|
{
|
|
DebugLog((DEB_ERROR, "Cannot log event, no handle!\n"));
|
|
return;
|
|
}
|
|
|
|
_snwprintf(Description, RTL_NUMBER_OF(Description) - 1, L"%d", DescriptionID);
|
|
|
|
Status = CDBuildIntegrityVect(
|
|
&KdcEtypeCount,
|
|
KdcEtypes
|
|
);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// is there at least one etype in RequestEtypes supported?
|
|
//
|
|
|
|
for (ULONG i = 0; i < KdcEtypeCount; i++)
|
|
{
|
|
if ((AccountTicketInfo->UserAccountControl & USER_USE_DES_KEY_ONLY)
|
|
&& ((KdcEtypes[i] == KERB_ETYPE_RC4_LM)
|
|
|| (KdcEtypes[i]== KERB_ETYPE_RC4_MD4)
|
|
|| (KdcEtypes[i] == KERB_ETYPE_RC4_HMAC_OLD)
|
|
|| (KdcEtypes[i] == KERB_ETYPE_RC4_HMAC_OLD_EXP)
|
|
|| (KdcEtypes[i] == KERB_ETYPE_RC4_HMAC_NT)
|
|
|| (KdcEtypes[i] == KERB_ETYPE_RC4_HMAC_NT_EXP)
|
|
|| (KdcEtypes[i] == KERB_ETYPE_NULL)) )
|
|
{
|
|
continue;
|
|
}
|
|
|
|
for (PKERB_CRYPT_LIST cur = RequestEtypes; cur != NULL; cur = cur->next)
|
|
{
|
|
if ((LONG) KdcEtypes[i] == cur->value)
|
|
{
|
|
IsEtypeSupported = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
Status = KdcBuildEtypeStringFromCryptList(
|
|
RequestEtypes,
|
|
&RequestEtypeString
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DebugLog((DEB_ERROR, "KdcBuildEtypeFromCryptList failed\n"));
|
|
goto cleanup;
|
|
}
|
|
|
|
Status = KdcBuildEtypeStringFromStoredCredential(
|
|
AccountTicketInfo->Passwords,
|
|
&StoredEtypeString
|
|
);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
DebugLog((DEB_ERROR, "KdcBuildEtypeFromStoredCredential failed\n"));
|
|
goto cleanup;
|
|
}
|
|
|
|
if (EventId == KDCEVENT_NO_KEY_INTERSECTION_TGS)
|
|
{
|
|
if (!ARGUMENT_PRESENT(ServerName))
|
|
{
|
|
DebugLog((DEB_ERROR, "Invalid arg to KdcReportKeyError: missing ServerName!\n"));
|
|
DsysAssert(FALSE);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
else if (EventId != KDCEVENT_NO_KEY_INTERSECTION_AS)
|
|
{
|
|
DebugLog((DEB_ERROR, "Invalid arg to KdcReportKeyError: unexpected event id %#x!\n", EventId));
|
|
DsysAssert(FALSE);
|
|
goto cleanup;
|
|
}
|
|
|
|
Strings[0] = ServerName ? ServerName->Buffer : KDC_PRINCIPAL_NAME;
|
|
Strings[1] = AccountName->Buffer;
|
|
Strings[2] = Description;
|
|
Strings[3] = RequestEtypeString;
|
|
Strings[4] = StoredEtypeString;
|
|
|
|
if (IsEtypeSupported)
|
|
{
|
|
//
|
|
// these can be corrected by resetting/changing the passwords
|
|
//
|
|
|
|
Strings[5] = AccountTicketInfo->AccountName.Buffer;
|
|
NumberOfStrings = 6;
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// these can not be corrected by resetting/changing the password
|
|
//
|
|
|
|
DebugLog((DEB_ERROR, "KdcReportKeyError etype not supported %ws\n", RequestEtypeString));
|
|
|
|
if (EventId == KDCEVENT_NO_KEY_INTERSECTION_TGS)
|
|
{
|
|
EventId = KDCEVENT_UNSUPPORTED_ETYPE_REQUEST_TGS;
|
|
}
|
|
else if (EventId == KDCEVENT_NO_KEY_INTERSECTION_AS)
|
|
{
|
|
EventId = KDCEVENT_UNSUPPORTED_ETYPE_REQUEST_AS;
|
|
}
|
|
|
|
NumberOfStrings = 5;
|
|
}
|
|
|
|
if ((rv = NetpEventlogWrite(
|
|
hEventLog,
|
|
EventId,
|
|
EVENTLOG_ERROR_TYPE,
|
|
NULL,
|
|
0, // no raw data
|
|
(LPWSTR *) Strings,
|
|
NumberOfStrings
|
|
)) != ERROR_SUCCESS)
|
|
|
|
{
|
|
DebugLog((DEB_ERROR, "KdcReportKeyError NetpEventlogWrite( 0x%x ) failed - %u\n", EventId, rv));
|
|
}
|
|
|
|
cleanup:
|
|
|
|
if (NULL != RequestEtypeString)
|
|
{
|
|
MIDL_user_free(RequestEtypeString);
|
|
}
|
|
|
|
if (NULL != StoredEtypeString)
|
|
{
|
|
MIDL_user_free(StoredEtypeString);
|
|
}
|
|
}
|
|
|
|
void
|
|
KdcReportInvalidMessage(
|
|
IN ULONG EventId,
|
|
IN PCWSTR pMesageDescription
|
|
)
|
|
{
|
|
ULONG NumberOfStrings;
|
|
PWSTR Strings[ MAX_EVENT_STRINGS ] = {0};
|
|
DWORD rv;
|
|
|
|
if (!hEventLog)
|
|
{
|
|
DebugLog((DEB_ERROR, "KdcReportInvalidMessage cannot log event, no handle!\n"));
|
|
return;
|
|
}
|
|
|
|
Strings[0] = (PWSTR) pMesageDescription;
|
|
NumberOfStrings = 1;
|
|
|
|
if ((rv = NetpEventlogWrite(
|
|
hEventLog,
|
|
EventId,
|
|
EVENTLOG_ERROR_TYPE,
|
|
NULL,
|
|
0, // no raw data
|
|
(LPWSTR *) Strings,
|
|
NumberOfStrings
|
|
)) != ERROR_SUCCESS)
|
|
|
|
{
|
|
DebugLog((DEB_ERROR, "KdcReportInvalidMessage NetpEventlogWrite( 0x%x ) failed - %u\n", EventId, rv));
|
|
}
|
|
}
|
|
|
|
void
|
|
KdcReportBadClientCertificate(
|
|
IN PUNICODE_STRING CName,
|
|
IN PVOID ChainStatus,
|
|
IN ULONG ChainStatusSize,
|
|
IN DWORD Error
|
|
)
|
|
{
|
|
|
|
LPWSTR UCName = NULL;
|
|
LPWSTR UCRealm = NULL;
|
|
PUNICODE_STRING Realm = SecData.KdcRealmName();
|
|
LPWSTR MessageBuffer = NULL;
|
|
DWORD MessageSize = 0;
|
|
|
|
//
|
|
// May not want this logged.
|
|
//
|
|
if (( KdcExtraLogLevel & LOG_PKI_ERRORS ) == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//
|
|
// Put the strings together - Null terminate the buffers...
|
|
//
|
|
SafeAllocaAllocate(UCName, (CName->MaximumLength + sizeof(WCHAR)) );
|
|
|
|
if (UCName == NULL)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
RtlZeroMemory(
|
|
UCName,
|
|
(CName->MaximumLength + sizeof(WCHAR))
|
|
);
|
|
|
|
RtlCopyMemory(
|
|
UCName,
|
|
CName->Buffer,
|
|
CName->Length
|
|
);
|
|
|
|
SafeAllocaAllocate(UCRealm,(Realm->MaximumLength + sizeof(WCHAR)) );
|
|
|
|
if (UCRealm == NULL)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
RtlZeroMemory(
|
|
UCRealm,
|
|
(Realm->MaximumLength + sizeof(WCHAR))
|
|
);
|
|
|
|
RtlCopyMemory(
|
|
UCRealm,
|
|
Realm->Buffer,
|
|
Realm->Length
|
|
);
|
|
|
|
|
|
MessageSize = FormatMessageW(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
|
|
NULL,
|
|
Error,
|
|
0,
|
|
(WCHAR*) &MessageBuffer,
|
|
MessageSize,
|
|
NULL
|
|
);
|
|
|
|
if ( MessageSize == 0)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
ReportServiceEvent(
|
|
EVENTLOG_WARNING_TYPE,
|
|
KDCEVENT_INVALID_CLIENT_CERTIFICATE,
|
|
ChainStatusSize,
|
|
ChainStatus,
|
|
3,
|
|
UCRealm,
|
|
UCName,
|
|
MessageBuffer
|
|
);
|
|
Cleanup:
|
|
|
|
SafeAllocaFree(UCName);
|
|
SafeAllocaFree(UCRealm);
|
|
|
|
if ( MessageBuffer )
|
|
{
|
|
LocalFree(MessageBuffer);
|
|
}
|
|
}
|
|
|
|
VOID
|
|
KdcReportPolicyErrorEvent(
|
|
IN ULONG EventType,
|
|
IN ULONG EventId,
|
|
IN PUNICODE_STRING CName,
|
|
IN PUNICODE_STRING SName,
|
|
IN NTSTATUS NtStatus,
|
|
IN ULONG RawDataSize,
|
|
IN OPTIONAL PBYTE RawDataBuffer
|
|
)
|
|
{
|
|
ULONG NumberOfStrings = 0;
|
|
PWSTR Strings[ MAX_EVENT_STRINGS ] = {0};
|
|
ULONG rv = 0;
|
|
|
|
if (!hEventLog)
|
|
{
|
|
DebugLog((DEB_ERROR, "KdcReportPolicyEvent cannot log event, no handle!\n"));
|
|
return;
|
|
}
|
|
|
|
//
|
|
// may not want this logged
|
|
//
|
|
|
|
if (( KdcExtraLogLevel & LOG_POLICY_ERROR ) == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if ((EventId == KDCEVENT_POLICY_USER2USER_REQUIRED) && (NtStatus == STATUS_USER2USER_REQUIRED))
|
|
{
|
|
NumberOfStrings = 2;
|
|
|
|
//
|
|
// this is in the error path, validate buffers
|
|
//
|
|
|
|
if ((CName->Buffer == NULL) || (SName->Buffer == NULL))
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
//
|
|
// Put the strings together - Null terminate the buffers...
|
|
//
|
|
|
|
SafeAllocaAllocate(Strings[0], (CName->Length + sizeof(WCHAR)));
|
|
|
|
if (Strings[0] == NULL)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
RtlZeroMemory(
|
|
Strings[0],
|
|
(CName->Length + sizeof(WCHAR))
|
|
);
|
|
|
|
RtlCopyMemory(
|
|
Strings[0],
|
|
CName->Buffer,
|
|
CName->Length
|
|
);
|
|
|
|
SafeAllocaAllocate(Strings[1], (SName->Length + sizeof(WCHAR)));
|
|
|
|
if (Strings[1] == NULL)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
RtlZeroMemory(
|
|
Strings[1],
|
|
(SName->Length + sizeof(WCHAR))
|
|
);
|
|
|
|
RtlCopyMemory(
|
|
Strings[1],
|
|
SName->Buffer,
|
|
SName->Length
|
|
);
|
|
}
|
|
else
|
|
{
|
|
D_DebugLog((DEB_ERROR, "KdcReportPolicyEvent unsupported event id %#x\n", EventId));
|
|
goto Cleanup;
|
|
}
|
|
|
|
if ((rv = NetpEventlogWrite(
|
|
hEventLog,
|
|
EventId,
|
|
EventType,
|
|
NULL, // RawDataBuffer
|
|
0, // RawDataSize
|
|
(PWSTR *) Strings,
|
|
NumberOfStrings
|
|
)) != ERROR_SUCCESS)
|
|
|
|
{
|
|
DebugLog((DEB_ERROR, "KdcReportPolicyEvent NetpEventlogWrite( event id %#x ) failed with %#x\n", EventId, rv));
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
for (ULONG i = 0; i <= NumberOfStrings; i++)
|
|
{
|
|
SafeAllocaFree(Strings[i]);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
#define S4U_EVENT_STRING_COUNT 3
|
|
|
|
|
|
VOID
|
|
KdcReportS4UGroupExpansionError(
|
|
IN PUSER_INTERNAL6_INFORMATION UserInfo,
|
|
IN PKDC_S4U_TICKET_INFO CallerInfo,
|
|
IN DWORD Error
|
|
)
|
|
{
|
|
KERBERR KerbErr;
|
|
ULONG rv = 0;
|
|
PWSTR CallerSName = NULL;
|
|
PWSTR Client = NULL;
|
|
PWSTR Strings[S4U_EVENT_STRING_COUNT];
|
|
UNICODE_STRING CallerName ={0};
|
|
|
|
if (!hEventLog)
|
|
{
|
|
DebugLog((DEB_ERROR, "KdcReportPolicyEvent cannot log event, no handle!\n"));
|
|
return;
|
|
}
|
|
|
|
//
|
|
// may not want this logged
|
|
//
|
|
if (( KdcExtraLogLevel & LOG_S4USELF_ACCESS_ERROR ) == 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
KerbErr = KerbConvertKdcNameToString(
|
|
&CallerName,
|
|
CallerInfo->RequestorServiceName,
|
|
NULL
|
|
);
|
|
|
|
if (!KERB_SUCCESS( KerbErr ))
|
|
{
|
|
return;
|
|
}
|
|
|
|
CallerSName = CallerName.Buffer;
|
|
|
|
//
|
|
// Verify that the user info string is null terminated.
|
|
//
|
|
SafeAllocaAllocate(Client, (UserInfo->I1.UserName.Length + sizeof(WCHAR)));
|
|
if (Client == NULL)
|
|
{
|
|
goto Cleanup;
|
|
}
|
|
|
|
RtlZeroMemory(
|
|
Client,
|
|
(UserInfo->I1.UserName.Length + sizeof(WCHAR))
|
|
);
|
|
|
|
RtlCopyMemory(
|
|
Client,
|
|
UserInfo->I1.UserName.Buffer,
|
|
UserInfo->I1.UserName.Length
|
|
);
|
|
|
|
Strings[0] = CallerSName;
|
|
Strings[1] = CallerInfo->RequestorServiceRealm.Buffer;
|
|
Strings[2] = Client;
|
|
|
|
|
|
if ((rv = NetpEventlogWrite(
|
|
hEventLog,
|
|
KDCEVENT_S4USELF_ACCESS_FAILED,
|
|
EVENTLOG_WARNING_TYPE,
|
|
(LPBYTE)&Error,
|
|
sizeof(DWORD), // RawDataSize
|
|
(PWSTR *) Strings,
|
|
S4U_EVENT_STRING_COUNT
|
|
)) != ERROR_SUCCESS)
|
|
|
|
{
|
|
D_DebugLog((DEB_ERROR, "KdcReportPolicyEvent NetpEventlogWrite( event id %#x ) failed with %#x\n", KDCEVENT_S4USELF_ACCESS_FAILED, rv));
|
|
}
|
|
|
|
Cleanup:
|
|
|
|
KerbFreeString( &CallerName );
|
|
if ( Client )
|
|
{
|
|
SafeAllocaFree( Client );
|
|
}
|
|
|
|
}
|