windows-nt/Source/XPSP1/NT/sdktools/pview/lsa.c
2020-09-26 16:20:57 +08:00

265 lines
6.6 KiB
C

/****************************************************************************
PROGRAM: LSA.C
PURPOSE: Utility routines that access the LSA.
****************************************************************************/
#include "pviewp.h"
#include <ntlsa.h>
#include <string.h>
// Module global that holds handle to LSA once it has been opened.
static LSA_HANDLE LsaHandle = NULL;
LSA_HANDLE OpenLsa(VOID);
VOID CloseLsa(LSA_HANDLE);
/****************************************************************************
FUNCTION: LsaInit
PURPOSE: Does any initialization required for this module
RETURNS: TRUE on success, FALSE on failure
****************************************************************************/
BOOL LsaInit(VOID)
{
LsaHandle = OpenLsa();
return (LsaHandle != NULL);
return (TRUE);
}
/****************************************************************************
FUNCTION: LsaTerminate
PURPOSE: Does any cleanup required for this module
RETURNS: TRUE on success, FALSE on failure
****************************************************************************/
BOOL LsaTerminate(VOID)
{
if (LsaHandle != NULL) {
CloseLsa(LsaHandle);
}
LsaHandle = NULL;
return(TRUE);
}
/****************************************************************************
FUNCTION: OpenLsa
PURPOSE: Opens the Lsa
Returns handle to Lsa or NULL on failure
****************************************************************************/
LSA_HANDLE OpenLsa(VOID)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
LSA_HANDLE ConnectHandle = NULL;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
//
// Set up the Security Quality Of Service
//
SecurityQualityOfService.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
SecurityQualityOfService.ImpersonationLevel = SecurityImpersonation;
SecurityQualityOfService.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
SecurityQualityOfService.EffectiveOnly = FALSE;
//
// Set up the object attributes prior to opening the LSA.
//
InitializeObjectAttributes(&ObjectAttributes,
NULL,
0L,
(HANDLE)NULL,
NULL);
//
// The InitializeObjectAttributes macro presently stores NULL for
// the SecurityQualityOfService field, so we must manually copy that
// structure for now.
//
ObjectAttributes.SecurityQualityOfService = &SecurityQualityOfService;
//
// Open a handle to the LSA. Specifying NULL for the Server means that the
// server is the same as the client.
//
Status = LsaOpenPolicy(NULL,
&ObjectAttributes,
POLICY_LOOKUP_NAMES,
&ConnectHandle
);
if (!NT_SUCCESS(Status)) {
DbgPrint("LSM - Lsa Open failed 0x%lx\n", Status);
return NULL;
}
return(ConnectHandle);
}
/****************************************************************************
FUNCTION: CloseLsa
PURPOSE: Closes the Lsa
****************************************************************************/
VOID CloseLsa(
LSA_HANDLE LsaHandle)
{
NTSTATUS Status;
Status = LsaClose(LsaHandle);
if (!NT_SUCCESS(Status)) {
DbgPrint("LSM - Lsa Close failed 0x%lx\n", Status);
}
return;
}
/****************************************************************************
FUNCTION: SID2Name
PURPOSE: Converts a SID into a readable string.
RETURNS : TRUE on success otherwise FALSE.
****************************************************************************/
BOOL SID2Name(
PSID Sid,
LPSTR String,
USHORT MaxStringBytes)
{
NTSTATUS Status;
ANSI_STRING AnsiName;
PLSA_REFERENCED_DOMAIN_LIST DomainList;
PLSA_TRANSLATED_NAME NameList;
if (LsaHandle == NULL) {
DbgPrint("SECEDIT : Lsa not open yet\n");
return(FALSE);
}
Status = LsaLookupSids(LsaHandle, 1, &Sid, &DomainList, &NameList);
if (NT_SUCCESS(Status)) {
// Convert to ansi string
RtlUnicodeStringToAnsiString(&AnsiName, &NameList->Name, TRUE);
// Free up the returned data
LsaFreeMemory((PVOID)DomainList);
LsaFreeMemory((PVOID)NameList);
// Copy the ansi string into our local variable
strncpy(String, AnsiName.Buffer, MaxStringBytes);
// Free up the ansi string
RtlFreeAnsiString(&AnsiName);
} else {
UNICODE_STRING UnicodeName;
if (NT_SUCCESS(RtlConvertSidToUnicodeString(&UnicodeName, Sid, TRUE))) {
DbgPrint("LsaLookupSids failed for sid <%wZ>, error = 0x%lx\n", &UnicodeName, Status);
AnsiName.Buffer = String;
AnsiName.MaximumLength = MaxStringBytes;
RtlUnicodeStringToAnsiString(&AnsiName, &UnicodeName, FALSE);
RtlFreeUnicodeString(&UnicodeName);
} else {
DbgPrint("LsaLookupSids failed, error = 0x%lx\n", Status);
return(FALSE);
}
}
return(TRUE);
}
/****************************************************************************
FUNCTION: PRIV2Name
PURPOSE: Converts a PRIVILEGE into a readable string.
RETURNS : TRUE on success otherwise FALSE.
****************************************************************************/
BOOL PRIV2Name(
LUID Privilege,
LPSTR lpstr,
UINT MaxStringBytes)
{
NTSTATUS Status;
STRING String;
PUNICODE_STRING UString;
if (LsaHandle == NULL) {
DbgPrint("SECEDIT : Lsa not open yet\n");
return(FALSE);
}
Status = LsaLookupPrivilegeName(LsaHandle, &Privilege, &UString);
if (!NT_SUCCESS(Status)) {
DbgPrint("SECEDIT: LsaLookupPrivilegeName failed, status = 0x%lx\n", Status);
strcpy(lpstr, "<Unknown>");
} else {
//
// Convert it to ANSI - because that's what the rest of the app is.
//
if (UString->Length > (USHORT)MaxStringBytes) {
DbgPrint("SECEDIT: Truncating returned privilege name: *%S*\n", UString);
UString->Length = (USHORT)MaxStringBytes;
DbgPrint(" To: *%S*\n", UString);
}
String.Length = 0;
String.MaximumLength = (USHORT)MaxStringBytes;
String.Buffer = lpstr;
Status = RtlUnicodeStringToAnsiString( &String, UString, FALSE );
ASSERT(NT_SUCCESS(Status));
LsaFreeMemory( UString );
}
return(TRUE);
}