windows-nt/Source/XPSP1/NT/ds/security/base/lsa/uclient/ctlklsa.c
2020-09-26 16:20:57 +08:00

580 lines
13 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
ctlklsa.c
Abstract:
Local Security Authority Subsystem - Short CT for Lsa LookupAccountName/Sid
This is a small test that simply calls the LsaLookupName/Sid API once.
Usage:
ctlklsa \\ServerName [-p] -a AccountName ... AccountName
-p - pause before name and sid lookup operation
-a - start of list of account names
Building Instructions:
nmake UMTEST=ctlklsa UMTYPE=console
Author:
Environment:
Revision History:
--*/
#include "lsaclip.h"
VOID
DumpSID(
IN PSID s
);
VOID
CtPause(
);
#define LSA_WIN_STANDARD_BUFFER_SIZE 0x000000200L
VOID __cdecl
main(argc, argv)
int argc;
char **argv;
{
NTSTATUS
Status = STATUS_SUCCESS,
SidStatus;
ULONG
Index,
ArgCount = (ULONG) argc,
DomainIndex,
NameIndex,
NameCount,
DomainSidLength;
ANSI_STRING
NamesAnsi[ LSA_WIN_STANDARD_BUFFER_SIZE],
SystemNameAnsi;
UNICODE_STRING
Names[ LSA_WIN_STANDARD_BUFFER_SIZE],
SystemName;
PUNICODE_STRING
DomainName;
PSID
Sid = NULL,
*Sids = NULL;
SECURITY_QUALITY_OF_SERVICE
SecurityQualityOfService;
OBJECT_ATTRIBUTES
ObjectAttributes;
LSA_HANDLE
PolicyHandle;
PLSA_REFERENCED_DOMAIN_LIST
ReferencedDomains = NULL,
ReferencedSidsDomains = NULL;
PLSA_TRANSLATED_SID
TranslatedSids = NULL;
PLSA_TRANSLATED_NAME
TranslatedNames = NULL;
UCHAR
SubAuthorityCount;
BOOLEAN
Pause = FALSE,
DoLookupSids = TRUE;
if (argc < 4) {
printf("usage: ctlkacct <ServerName> [-p] -a <AccountName> [<AccountName> ...]\n\n");
printf(" -p - pause before name and sid lookup operations\n");
printf(" -a - start of list of account names\n\n");
printf("example:\n");
printf(" ctlklsa \\\\jimk -p -a interactive \"domain guests\" administrators\n\n");
return;
}
NameIndex = 0;
//
// Capture argument 1, the Server Name
//
RtlInitString( &SystemNameAnsi, (PUCHAR) argv[1] );
Status = RtlAnsiStringToUnicodeString(
&SystemName,
&SystemNameAnsi,
TRUE
);
if (!NT_SUCCESS(Status)) {
goto MainError;
}
for (Index = 2; Index < ArgCount; Index++) {
if (strncmp(argv[Index], "-p", 2) == 0) {
//
// The caller wants a pause before each lookup call.
//
Pause = TRUE;
} else if (strncmp(argv[Index], "-a", 2) == 0) {
Index++;
while (Index < ArgCount) {
if (strncmp(argv[Index], "-", 1) == 0) {
Index--;
break;
}
//
// Capture the Account Name as a Unicode String.
//
RtlInitString( &NamesAnsi[ NameIndex ], argv[Index] );
Status = RtlAnsiStringToUnicodeString(
&Names[ NameIndex ],
&NamesAnsi[ NameIndex ],
TRUE
);
if (!NT_SUCCESS(Status)) {
break;
}
NameIndex++;
Index++;
}
if (Index == ArgCount) {
break;
}
}
}
if (!NT_SUCCESS(Status)) {
goto MainError;
}
NameCount = NameIndex;
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,
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 the LSA Policy Database for the target system. This is the
// starting point for the Name Lookup operation.
//
Status = LsaOpenPolicy(
&SystemName,
&ObjectAttributes,
POLICY_LOOKUP_NAMES,
&PolicyHandle
);
if (!NT_SUCCESS(Status)) {
goto MainError;
}
if (Pause) {
printf( "\n\n..... Pausing before name lookup \n ");
CtPause( );
}
//
// Attempt to translate the Names to Sids.
//
Status = LsaLookupNames(
PolicyHandle,
NameCount,
Names,
&ReferencedDomains,
&TranslatedSids
);
if (!NT_SUCCESS(Status)) {
goto MainError;
}
//
// Build the Sids from the output.
//
Sids = (PSID *) LocalAlloc( 0, NameCount * sizeof (PSID) );
if (Sids == NULL) {
Status = STATUS_INSUFFICIENT_RESOURCES;
goto MainError;
}
for (NameIndex = 0; NameIndex < NameCount; NameIndex++) {
if (TranslatedSids[NameIndex].Use == SidTypeUnknown) {
Sids[NameIndex] = NULL;
DoLookupSids = FALSE;
} else {
DomainIndex = TranslatedSids[NameIndex].DomainIndex;
DomainSidLength = RtlLengthSid(
ReferencedDomains->Domains[DomainIndex].Sid
);
Sid = (PSID) LocalAlloc( (UINT) 0, (UINT) (DomainSidLength + sizeof(ULONG)) );
if (Sid == NULL) {
printf(" ** ERROR - couldn't allocate heap !!\n");
return;
}
RtlMoveMemory(
Sid,
ReferencedDomains->Domains[DomainIndex].Sid,
DomainSidLength
);
if (TranslatedSids[NameIndex].Use != SidTypeDomain) {
(*RtlSubAuthorityCountSid( Sid ))++;
SubAuthorityCount = *RtlSubAuthorityCountSid( Sid );
*RtlSubAuthoritySid(Sid,SubAuthorityCount - (UCHAR) 1) =
TranslatedSids[NameIndex].RelativeId;
}
Sids[NameIndex] = Sid;
}
}
//
// Pause before SID lookup...
//
if (!DoLookupSids) {
printf("\n\n Unknown Name causing sid lookup to be skipped\n");
} else {
if (Pause) {
printf( "\n\n..... Pausing before SID lookup \n ");
CtPause();
}
//
// Now translate the Sids back to Names
//
SidStatus = LsaLookupSids(
PolicyHandle,
NameCount,
(PSID *) Sids,
&ReferencedSidsDomains,
&TranslatedNames
);
}
/*
* Print information returned by LookupAccountName
*/
printf(
"*********************************************\n"
"Information returned by LookupAccountName\n"
"*********************************************\n\n"
);
for (NameIndex = 0; NameIndex < NameCount; NameIndex++) {
printf(" Name looked up: *%wZ*\n", &Names[NameIndex]);
printf(" Use = ");
switch (TranslatedSids[NameIndex].Use) {
case SidTypeUser:
printf("SidTypeUser\n");
break;
case SidTypeGroup:
printf("SidTypeGroup\n");
break;
case SidTypeDomain:
printf("SidTypeDomain\n");
break;
case SidTypeAlias:
printf("SidTypeAlias\n");
break;
case SidTypeWellKnownGroup:
printf("SidTypeWellKnownGroup\n");
break;
case SidTypeDeletedAccount:
printf("SidTypeDeletedAccount\n");
break;
case SidTypeInvalid:
printf("SidTypeInvalid\n");
break;
case SidTypeUnknown:
printf("SidTypeUnknown\n\n");
break;
default:
printf("Hmmm - something unusual came back !!!! \n\n");
break;
}
if (TranslatedSids[NameIndex].Use != SidTypeUnknown) {
printf(" Sid = " );
DumpSID((PSID) Sids[NameIndex]);
DomainIndex = TranslatedSids[NameIndex].DomainIndex;
DomainName = &ReferencedDomains->Domains[ DomainIndex ].Name;
printf(" Referenced Domain Name = *%wZ*\n\n", DomainName );
}
}
if (DoLookupSids) {
printf(
"*********************************************\n"
"Information returned by LookupAccountSid\n"
"*********************************************\n\n"
);
if (!NT_SUCCESS(SidStatus)) {
printf(" Sid lookup failed. Status 0x%lx\n"
" Dumping sids that were being looked up...\n",
SidStatus);
}
for (NameIndex = 0; NameIndex < NameCount; NameIndex++) {
printf(" Sid = " );
DumpSID((PSID) Sids[NameIndex]);
if (NT_SUCCESS(SidStatus)) {
printf(" Sid Use = ");
switch (TranslatedNames[NameIndex].Use) {
case SidTypeUser:
printf("SidTypeUser\n");
break;
case SidTypeGroup:
printf("SidTypeGroup\n");
break;
case SidTypeDomain:
printf("SidTypeDomain\n");
break;
case SidTypeAlias:
printf("SidTypeAlias\n");
break;
case SidTypeWellKnownGroup:
printf("SidTypeWellKnownGroup\n");
break;
case SidTypeDeletedAccount:
printf("SidTypeDeletedAccount\n");
break;
case SidTypeInvalid:
printf("SidTypeInvalid\n");
break;
case SidTypeUnknown:
printf("SidTypeUnknown\n");
break;
default:
printf("Hmmm - unexpected value !!!\n");
break;
}
DomainIndex = TranslatedNames[NameIndex].DomainIndex;
DomainName = &ReferencedSidsDomains->Domains[ DomainIndex ].Name;
if (TranslatedNames[NameIndex].Use == SidTypeDomain) {
printf(
" Domain Name = *%wZ*\n\n",
DomainName
);
} else {
printf(
" Account Name = *%wZ*\n"
" Referenced Domain Name = *%wZ*\n\n",
&TranslatedNames[NameIndex].Name,
DomainName
);
}
}
}
}
MainFinish:
return;
MainError:
printf("Error: status = 0x%lx\n", Status);
goto MainFinish;
}
VOID
DumpSID(
IN PSID s
)
{
SID_IDENTIFIER_AUTHORITY
*a;
ULONG
id = 0,
i;
BOOLEAN
PrintValue = FALSE;
try {
a = GetSidIdentifierAuthority(s);
printf("s-1-");
for (i=0; i<5; i++) {
if ((a->Value[i] != 0) || PrintValue) {
printf("%02x", a->Value[i]);
PrintValue = TRUE;
}
}
printf("%02x", a->Value[5]);
for (i = 0; i < (ULONG) *GetSidSubAuthorityCount(s); i++) {
printf("-0x%lx", *GetSidSubAuthority(s, i));
}
} except (EXCEPTION_EXECUTE_HANDLER) {
printf("<invalid pointer (0x%lx)>\n", s);
}
printf("\n");
}
VOID
CtPause(
)
{
CHAR
IgnoreInput[300];
printf("Press <ENTER> to continue . . .");
gets( &IgnoreInput[0] );
return;
}