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

1077 lines
27 KiB
C
Raw 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:
adtbuild.c
Abstract:
Local Security Authority - Audit Log Management
Functions in this module build unicode strings for
various parameter types. Some parameter string build
routines may also be found in other modules (such as
LsapAdtBuildAccessesString() in adtobjs.c).
Author:
Jim Kelly (JimK) 29-Oct-1992
Environment:
Revision History:
--*/
#include <lsapch2.h>
#include "adtp.h"
#ifndef LSAP_ADT_UMTEST
//
// pick up definitions of privately callable LSA services ONLY if we
// aren't building a user mode test.
//
#endif
////////////////////////////////////////////////////////////////////////
// //
// Local Macro definitions and local function prototypes //
// //
////////////////////////////////////////////////////////////////////////
#ifdef LSAP_ADT_UMTEST
//
// Define all external routines that we won't pick up in a user mode test
//
NTSTATUS
LsapGetLogonSessionAccountInfo(
IN PLUID Value,
OUT PUNICODE_STRING AccountName,
OUT PUNICODE_STRING AuthorityName
);
#endif
////////////////////////////////////////////////////////////////////////
// //
// Data types used within this module //
// //
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// //
// Variables global within this module //
// //
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
// //
// Services exported by this module. //
// //
////////////////////////////////////////////////////////////////////////
NTSTATUS
LsapAdtBuildUlongString(
IN ULONG Value,
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
Routine Description:
This function builds a unicode string representing the passed value.
The resultant string will be formatted as a decimal value with not
more than 10 digits.
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 buffer 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;
//
// Maximum length is 10 wchar characters plus a null termination character.
//
ResultantString->Length = 0;
ResultantString->MaximumLength = 11 * sizeof(WCHAR); // 10 digits & null termination
ResultantString->Buffer = RtlAllocateHeap( RtlProcessHeap(), 0,
ResultantString->MaximumLength);
if (ResultantString->Buffer == NULL) {
return(STATUS_NO_MEMORY);
}
Status = RtlIntegerToUnicodeString( Value, 10, ResultantString );
ASSERT(NT_SUCCESS(Status));
(*FreeWhenDone) = TRUE;
return(STATUS_SUCCESS);
}
NTSTATUS
LsapAdtBuildHexUlongString(
IN ULONG Value,
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
Routine Description:
This function builds a unicode string representing the passed value.
The resultant string will be formatted as a hexidecimal value with not
more than 10 digits.
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 buffer 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;
//
// Maximum length is 10 wchar characters plus a null termination character.
//
ResultantString->Length = 0;
ResultantString->MaximumLength = 11 * sizeof(WCHAR); // 8 digits, a 0x, & null termination
ResultantString->Buffer = RtlAllocateHeap( RtlProcessHeap(), 0,
ResultantString->MaximumLength);
if (ResultantString->Buffer == NULL) {
return(STATUS_NO_MEMORY);
}
ResultantString->Buffer[0] = L'0';
ResultantString->Buffer[1] = L'x';
ResultantString->Buffer += 2;
Status = RtlIntegerToUnicodeString( Value, 16, ResultantString );
ASSERT(NT_SUCCESS(Status));
//
// Subtract off the two
//
ResultantString->Buffer -= 2;
ResultantString->Length += 2 * sizeof(WCHAR);
(*FreeWhenDone) = TRUE;
return(STATUS_SUCCESS);
}
NTSTATUS
LsapAdtBuildPtrString(
IN PVOID Value,
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
Routine Description:
This function builds a unicode string representing the passed pointer.
The resultant string will be formatted as a decimal value.
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 buffer 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 = STATUS_SUCCESS;
USHORT NumChars;
ResultantString->Length = 0;
//
// Maximum length: sign (+ / -) + 20 decimal digits + null + 2 bonus == 24 chars
//
ResultantString->MaximumLength = 24 * sizeof(WCHAR);
ResultantString->Buffer = RtlAllocateHeap( RtlProcessHeap(), 0,
ResultantString->MaximumLength);
if (ResultantString->Buffer == NULL) {
Status = STATUS_NO_MEMORY;
} else {
NumChars = (USHORT) wsprintf( ResultantString->Buffer, L"%Id", Value );
ResultantString->Length = NumChars * sizeof(WCHAR);
(*FreeWhenDone) = TRUE;
}
return Status;
}
NTSTATUS
LsapAdtBuildLuidString(
IN PLUID Value,
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
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 buffer 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;
WCHAR Buffer[16];
IntegerString.Buffer = (PWCHAR)&Buffer[0];
IntegerString.MaximumLength = sizeof(Buffer);
//
// 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" );
ASSERT(NT_SUCCESS(Status));
Status = RtlIntegerToUnicodeString( Value->HighPart, 16, &IntegerString );
ASSERT(NT_SUCCESS(Status));
Status = RtlAppendUnicodeToString( ResultantString, IntegerString.Buffer );
ASSERT(NT_SUCCESS(Status));
Status = RtlAppendUnicodeToString( ResultantString, L",0x" );
ASSERT(NT_SUCCESS(Status));
Status = RtlIntegerToUnicodeString( Value->LowPart, 16, &IntegerString );
ASSERT(NT_SUCCESS(Status));
Status = RtlAppendUnicodeToString( ResultantString, IntegerString.Buffer );
ASSERT(NT_SUCCESS(Status));
Status = RtlAppendUnicodeToString( ResultantString, L")" );
ASSERT(NT_SUCCESS(Status));
(*FreeWhenDone) = TRUE;
return(STATUS_SUCCESS);
}
NTSTATUS
LsapAdtBuildSidString(
IN PSID Value,
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
Routine Description:
This function builds a unicode string representing the passed LUID.
The resultant string will be formatted as follows:
S-1-281736-12-72-9-110
^ ^^ ^^ ^ ^^^
| | | | |
+-----+--+-+--+---- Decimal
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 buffer 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=STATUS_NO_MEMORY;
LPWSTR UniBuffer=NULL;
USHORT Len;
USHORT MaxLen;
*FreeWhenDone = FALSE;
//
// Note: RtlConvertSidToUnicodeString also uses a hard-coded const 256
// to generate the string SID.
//
MaxLen = (256+3) * sizeof(WCHAR);
UniBuffer = LsapAllocateLsaHeap(MaxLen);
if (UniBuffer)
{
ResultantString->Buffer = UniBuffer+2;
ResultantString->MaximumLength = MaxLen;
Status = RtlConvertSidToUnicodeString( ResultantString, Value, FALSE );
if (Status == STATUS_SUCCESS)
{
*FreeWhenDone = TRUE;
UniBuffer[0] = L'%';
UniBuffer[1] = L'{';
Len = ResultantString->Length / sizeof(WCHAR);
UniBuffer[Len+2] = L'}';
UniBuffer[Len+3] = UNICODE_NULL;
ResultantString->Buffer = UniBuffer;
ResultantString->Length = (Len+3)*sizeof(WCHAR);
}
else
{
LsapFreeLsaHeap(UniBuffer);
}
}
return(Status);
}
NTSTATUS
LsapAdtBuildDashString(
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
Routine Description:
This function returns a string containing a dash ("-").
This is commonly used to represent "No value" in audit records.
Arguments:
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 buffer of the ResultantString
must be freed to process heap when no longer needed.
Return Values:
STATUS_SUCCESS only.
--*/
{
RtlInitUnicodeString(ResultantString, L"-");
(*FreeWhenDone) = FALSE;
return STATUS_SUCCESS;
}
NTSTATUS
LsapAdtBuildFilePathString(
IN PUNICODE_STRING Value,
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
Routine Description:
This function builds a unicode string representing the passed file
path name. If possible, the string will be generated using drive
letters instead of object architecture namespace.
Arguments:
Value - The original file path name. This is expected (but does not
have to be) a standard NT object architecture name-space pathname.
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 buffer 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 = STATUS_SUCCESS;
//
// For now, don't do the conversion.
// Do this if we have time before we ship.
//
ResultantString->Length = Value->Length;
ResultantString->Buffer = Value->Buffer;
ResultantString->MaximumLength = Value->MaximumLength;
(*FreeWhenDone) = FALSE;
return(Status);
}
NTSTATUS
LsapAdtBuildLogonIdStrings(
IN PLUID LogonId,
OUT PUNICODE_STRING ResultantString1,
OUT PBOOLEAN FreeWhenDone1,
OUT PUNICODE_STRING ResultantString2,
OUT PBOOLEAN FreeWhenDone2,
OUT PUNICODE_STRING ResultantString3,
OUT PBOOLEAN FreeWhenDone3
)
/*++
Routine Description:
This function builds a 3 unicode strings representing the specified
logon ID. These strings will contain the username, domain, and
LUID string of the specified logon session (respectively).
Arguments:
Value - The logon ID.
ResultantString1 - 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.
This parameter will contain the username.
FreeWhenDone1 - If TRUE, indicates that the buffer of ResultantString1
must be freed to process heap when no longer needed.
ResultantString2 - 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.
This parameter will contain the username.
FreeWhenDone2 - If TRUE, indicates that the buffer of ResultantString2
must be freed to process heap when no longer needed.
ResultantString3 - 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.
This parameter will contain the username.
FreeWhenDone3 - If TRUE, indicates that the buffer of ResultantString3
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;
//
// Try to convert the LUID first.
//
Status = LsapAdtBuildLuidString( LogonId, ResultantString3, FreeWhenDone3 );
if (NT_SUCCESS(Status)) {
//
// Now get the username and domain names
//
Status = LsapGetLogonSessionAccountInfo( LogonId,
ResultantString1,
ResultantString2
);
if (NT_SUCCESS(Status)) {
(*FreeWhenDone1) = TRUE;
(*FreeWhenDone2) = TRUE;
} else {
//
// The LUID may be the system LUID
//
LUID SystemLuid = SYSTEM_LUID;
if ( RtlEqualLuid( LogonId, &SystemLuid )) {
RtlInitUnicodeString(ResultantString1, L"SYSTEM");
RtlInitUnicodeString(ResultantString2, L"SYSTEM");
(*FreeWhenDone1) = FALSE;
(*FreeWhenDone2) = FALSE;
Status = STATUS_SUCCESS;
} else {
//
// We have no clue what this is, just free what we've
// allocated.
//
if ((FreeWhenDone3)) {
LsapFreeLsaHeap( ResultantString3->Buffer );
}
}
}
}
return(Status);
}
NTSTATUS
LsapAdtBuildTimeString(
IN PLARGE_INTEGER Value,
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
Routine Description:
This function builds a unicode string representing the passed time.
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 buffer 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 = STATUS_UNSUCCESSFUL;
BOOL b = TRUE;
SYSTEMTIME SystemTime = {0};
FILETIME LocalFileTime = {0};
USHORT Length = 0;
WCHAR DataString[1024];
//
// First convert time to readable format.
//
b = FileTimeToLocalFileTime(
(PFILETIME)Value,
&LocalFileTime
);
if (!b) {
return Status;
}
b = FileTimeToSystemTime(
&LocalFileTime,
&SystemTime
);
if (!b) {
return Status;
}
if (0 == GetTimeFormat(
LOCALE_USER_DEFAULT,
0,
&SystemTime,
NULL,
DataString,
1024
)) {
return Status;
}
Length = (USHORT) wcslen( DataString );
ResultantString->MaximumLength = sizeof(WCHAR) * Length;
ResultantString->Length = sizeof(WCHAR) * Length;
ResultantString->Buffer = RtlAllocateHeap(
RtlProcessHeap(),
0,
sizeof(WCHAR) * Length
);
if (ResultantString->Buffer == NULL) {
return(STATUS_NO_MEMORY);
}
RtlCopyMemory(
ResultantString->Buffer,
DataString,
sizeof(WCHAR) * Length
);
*FreeWhenDone = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS
LsapAdtBuildDateString(
IN PLARGE_INTEGER Value,
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
Routine Description:
This function builds a unicode string representing the passed date.
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 buffer 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 = STATUS_UNSUCCESSFUL;
BOOL b = TRUE;
SYSTEMTIME SystemTime = {0};
FILETIME LocalFileTime = {0};
USHORT Length = 0;
WCHAR DataString[1024];
//
// First convert time to readable format.
//
b = FileTimeToLocalFileTime(
(PFILETIME)Value,
&LocalFileTime
);
if (!b) {
return Status;
}
b = FileTimeToSystemTime(
&LocalFileTime,
&SystemTime
);
if (!b) {
return Status;
}
if (0 == GetDateFormat(
LOCALE_USER_DEFAULT,
0,
&SystemTime,
NULL,
DataString,
1024
)) {
return Status;
}
Length = (USHORT) wcslen( DataString );
ResultantString->MaximumLength = sizeof(WCHAR) * Length;
ResultantString->Length = sizeof(WCHAR) * Length;
ResultantString->Buffer = RtlAllocateHeap(
RtlProcessHeap(),
0,
sizeof(WCHAR) * Length
);
if (ResultantString->Buffer == NULL) {
return(STATUS_NO_MEMORY);
}
RtlCopyMemory(
ResultantString->Buffer,
DataString,
sizeof(WCHAR) * Length
);
*FreeWhenDone = TRUE;
return STATUS_SUCCESS;
}
NTSTATUS
LsapAdtBuildGuidString(
IN LPGUID pGuid,
OUT PUNICODE_STRING ResultantString,
OUT PBOOLEAN FreeWhenDone
)
/*++
Routine Description:
This function builds a unicode string representing the passed GUID.
Arguments:
pGuid - The GUID to be transformed to printable format.
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.
The string will be in this format:
"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"
FreeWhenDone - If TRUE, indicates that the buffer 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.
--*/
{
//
// num chars required to hold {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
//
#define NUM_GUID_STRING_CHARS 38
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ResultantString->Length = NUM_GUID_STRING_CHARS*sizeof(WCHAR);
ResultantString->MaximumLength = (NUM_GUID_STRING_CHARS+1)*sizeof(WCHAR);
ResultantString->Buffer =
LsapAllocateLsaHeap(ResultantString->MaximumLength);
if (!ResultantString->Buffer)
{
*FreeWhenDone = FALSE;
Status = STATUS_NO_MEMORY;
goto Cleanup;
}
*FreeWhenDone = TRUE;
Status = STATUS_SUCCESS;
#if DBG
{
ULONG NumChars;
NumChars =
#endif
swprintf(ResultantString->Buffer,
L"{%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}",
pGuid->Data1,
pGuid->Data2,
pGuid->Data3,
pGuid->Data4[0],
pGuid->Data4[1],
pGuid->Data4[2],
pGuid->Data4[3],
pGuid->Data4[4],
pGuid->Data4[5],
pGuid->Data4[6],
pGuid->Data4[7]);
#if DBG
ASSERT( NumChars == NUM_GUID_STRING_CHARS );
}
#endif
Cleanup:
return Status;
}
////////////////////////////////////////////////////////////////////////
// //
// Services private to this module. //
// //
////////////////////////////////////////////////////////////////////////
#ifdef LSAP_ADT_UMTEST
//
// Define this routine only for user mode test
//
NTSTATUS
LsapGetLogonSessionAccountInfo(
IN PLUID Value,
OUT PUNICODE_STRING AccountName,
OUT PUNICODE_STRING AuthorityName
)
{
NTSTATUS Status = STATUS_NO_MEMORY;
if (RtlCreateUnicodeString( AccountName, L"Bullwinkle" )) {
if (RtlCreateUnicodeString( AuthorityName, L"The Rocky Show" )) {
Status = STATUS_SUCCESS;
} else {
RtlFreeHeap( RtlProcessHeap(), Accountame->Buffer );
}
}
return(Status);
}
#endif