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.
860 lines
23 KiB
860 lines
23 KiB
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
fttest.c
|
|
|
|
Abstract:
|
|
|
|
Component test for Ds*ForestTrustInformation API
|
|
|
|
Author:
|
|
|
|
Cliff Van Dyke (CliffV) August 11, 2000
|
|
|
|
Environment:
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
// #include <wincred.h>
|
|
// #include <credp.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
// #include <winnetwk.h>
|
|
|
|
#include <lmcons.h>
|
|
#include <lmerr.h>
|
|
#include <ntlsa.h>
|
|
#include <dsgetdc.h>
|
|
#include <ntstatus.dbg>
|
|
#include <winerror.dbg>
|
|
|
|
|
|
VOID
|
|
NlpDumpSid(
|
|
IN DWORD DebugFlag,
|
|
IN PSID Sid OPTIONAL
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Dumps a SID to the debugger output
|
|
|
|
Arguments:
|
|
|
|
DebugFlag - Debug flag to pass on to NlPrintRoutine
|
|
|
|
Sid - SID to output
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
|
|
//
|
|
// Output the SID
|
|
//
|
|
|
|
if ( Sid == NULL ) {
|
|
printf( "(null)\n");
|
|
} else {
|
|
UNICODE_STRING SidString;
|
|
NTSTATUS Status;
|
|
|
|
Status = RtlConvertSidToUnicodeString( &SidString, Sid, TRUE );
|
|
|
|
if ( !NT_SUCCESS(Status) ) {
|
|
printf( "Invalid 0x%lX\n", Status );
|
|
} else {
|
|
printf( "%wZ\n", &SidString );
|
|
RtlFreeUnicodeString( &SidString );
|
|
}
|
|
}
|
|
|
|
UNREFERENCED_PARAMETER( DebugFlag );
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
PrintTime(
|
|
LPSTR Comment,
|
|
LARGE_INTEGER ConvertTime
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Print the specified time
|
|
|
|
Arguments:
|
|
|
|
Comment - Comment to print in front of the time
|
|
|
|
Time - GMT time to print (Nothing is printed if this is zero)
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
//
|
|
// If we've been asked to convert an NT GMT time to ascii,
|
|
// Do so
|
|
//
|
|
|
|
if ( ConvertTime.QuadPart != 0 ) {
|
|
LARGE_INTEGER LocalTime;
|
|
TIME_FIELDS TimeFields;
|
|
NTSTATUS Status;
|
|
|
|
printf( "%s", Comment );
|
|
|
|
Status = RtlSystemTimeToLocalTime( &ConvertTime, &LocalTime );
|
|
if ( !NT_SUCCESS( Status )) {
|
|
printf( "Can't convert time from GMT to Local time\n" );
|
|
LocalTime = ConvertTime;
|
|
}
|
|
|
|
RtlTimeToTimeFields( &LocalTime, &TimeFields );
|
|
|
|
printf( "%8.8lx %8.8lx = %ld/%ld/%ld %ld:%2.2ld:%2.2ld\n",
|
|
ConvertTime.LowPart,
|
|
ConvertTime.HighPart,
|
|
TimeFields.Month,
|
|
TimeFields.Day,
|
|
TimeFields.Year,
|
|
TimeFields.Hour,
|
|
TimeFields.Minute,
|
|
TimeFields.Second );
|
|
}
|
|
}
|
|
|
|
LPSTR
|
|
FindSymbolicNameForStatus(
|
|
DWORD Id
|
|
)
|
|
{
|
|
ULONG i;
|
|
|
|
i = 0;
|
|
if (Id == 0) {
|
|
return "STATUS_SUCCESS";
|
|
}
|
|
|
|
if (Id & 0xC0000000) {
|
|
while (ntstatusSymbolicNames[ i ].SymbolicName) {
|
|
if (ntstatusSymbolicNames[ i ].MessageId == (NTSTATUS)Id) {
|
|
return ntstatusSymbolicNames[ i ].SymbolicName;
|
|
} else {
|
|
i += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
while (winerrorSymbolicNames[ i ].SymbolicName) {
|
|
if (winerrorSymbolicNames[ i ].MessageId == Id) {
|
|
return winerrorSymbolicNames[ i ].SymbolicName;
|
|
} else {
|
|
i += 1;
|
|
}
|
|
}
|
|
|
|
#ifdef notdef
|
|
while (neteventSymbolicNames[ i ].SymbolicName) {
|
|
if (neteventSymbolicNames[ i ].MessageId == Id) {
|
|
return neteventSymbolicNames[ i ].SymbolicName
|
|
} else {
|
|
i += 1;
|
|
}
|
|
}
|
|
#endif // notdef
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
VOID
|
|
PrintStatus(
|
|
NET_API_STATUS NetStatus
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Print a net status code.
|
|
|
|
Arguments:
|
|
|
|
NetStatus - The net status code to print.
|
|
|
|
Return Value:
|
|
|
|
None
|
|
|
|
--*/
|
|
{
|
|
printf( "Status = %lu 0x%lx", NetStatus, NetStatus );
|
|
|
|
switch (NetStatus) {
|
|
case NERR_Success:
|
|
printf( " NERR_Success" );
|
|
break;
|
|
|
|
case NERR_DCNotFound:
|
|
printf( " NERR_DCNotFound" );
|
|
break;
|
|
|
|
case NERR_UserNotFound:
|
|
printf( " NERR_UserNotFound" );
|
|
break;
|
|
|
|
case NERR_NetNotStarted:
|
|
printf( " NERR_NetNotStarted" );
|
|
break;
|
|
|
|
case NERR_WkstaNotStarted:
|
|
printf( " NERR_WkstaNotStarted" );
|
|
break;
|
|
|
|
case NERR_ServerNotStarted:
|
|
printf( " NERR_ServerNotStarted" );
|
|
break;
|
|
|
|
case NERR_BrowserNotStarted:
|
|
printf( " NERR_BrowserNotStarted" );
|
|
break;
|
|
|
|
case NERR_ServiceNotInstalled:
|
|
printf( " NERR_ServiceNotInstalled" );
|
|
break;
|
|
|
|
case NERR_BadTransactConfig:
|
|
printf( " NERR_BadTransactConfig" );
|
|
break;
|
|
|
|
default:
|
|
printf( " %s", FindSymbolicNameForStatus( NetStatus ) );
|
|
break;
|
|
|
|
}
|
|
|
|
printf( "\n" );
|
|
}
|
|
|
|
VOID
|
|
DumpFtinfo(
|
|
PLSA_FOREST_TRUST_INFORMATION Ftinfo
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Dumps the buffer content on to the debugger output.
|
|
|
|
Arguments:
|
|
|
|
Buffer: buffer pointer.
|
|
|
|
BufferSize: size of the buffer.
|
|
|
|
Return Value:
|
|
|
|
none
|
|
|
|
--*/
|
|
{
|
|
ULONG Index;
|
|
|
|
if ( Ftinfo == NULL ) {
|
|
printf( " (null)\n");
|
|
} else {
|
|
|
|
for ( Index=0; Index<Ftinfo->RecordCount; Index++ ) {
|
|
|
|
switch ( Ftinfo->Entries[Index]->ForestTrustType ) {
|
|
case ForestTrustTopLevelName:
|
|
printf( " TLN: %wZ",
|
|
&Ftinfo->Entries[Index]->ForestTrustData.TopLevelName );
|
|
break;
|
|
case ForestTrustTopLevelNameEx:
|
|
printf( " TEX: %wZ",
|
|
&Ftinfo->Entries[Index]->ForestTrustData.TopLevelName );
|
|
break;
|
|
case ForestTrustDomainInfo:
|
|
printf( " Dom: %wZ (%wZ)",
|
|
&Ftinfo->Entries[Index]->ForestTrustData.DomainInfo.DnsName,
|
|
&Ftinfo->Entries[Index]->ForestTrustData.DomainInfo.NetbiosName );
|
|
break;
|
|
default:
|
|
printf( " Invalid Type: %ld", Ftinfo->Entries[Index]->ForestTrustType );
|
|
}
|
|
|
|
if ( Ftinfo->Entries[Index]->Flags ) {
|
|
ULONG Flags = Ftinfo->Entries[Index]->Flags;
|
|
|
|
printf(" (" );
|
|
#define DoFlag( _flag, _text ) \
|
|
if ( Flags & _flag ) { \
|
|
printf( _text ); \
|
|
Flags &= ~_flag; \
|
|
}
|
|
|
|
switch ( Ftinfo->Entries[Index]->ForestTrustType ) {
|
|
case ForestTrustTopLevelName:
|
|
case ForestTrustTopLevelNameEx:
|
|
|
|
DoFlag( LSA_TLN_DISABLED_NEW, " TlnNew" );
|
|
DoFlag( LSA_TLN_DISABLED_ADMIN, " TlnAdmin" );
|
|
DoFlag( LSA_TLN_DISABLED_CONFLICT, " TlnConflict" );
|
|
}
|
|
|
|
switch ( Ftinfo->Entries[Index]->ForestTrustType ) {
|
|
case ForestTrustDomainInfo:
|
|
DoFlag( LSA_SID_DISABLED_ADMIN, " SidAdmin" );
|
|
DoFlag( LSA_SID_DISABLED_CONFLICT, " SidConflict" );
|
|
|
|
DoFlag( LSA_NB_DISABLED_ADMIN, " NbAdmin" );
|
|
DoFlag( LSA_NB_DISABLED_CONFLICT, " NbConflict" );
|
|
}
|
|
|
|
if ( Flags != 0 ) {
|
|
printf(" 0x%lX", Flags);
|
|
}
|
|
|
|
printf(")" );
|
|
|
|
}
|
|
|
|
switch ( Ftinfo->Entries[Index]->ForestTrustType ) {
|
|
case ForestTrustDomainInfo:
|
|
printf(" ");
|
|
NlpDumpSid( 0, Ftinfo->Entries[Index]->ForestTrustData.DomainInfo.Sid );
|
|
break;
|
|
default:
|
|
printf("\n");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Structure describing an Ftinfo entry
|
|
//
|
|
|
|
typedef struct _AN_ENTRY {
|
|
ULONG Flags;
|
|
LSA_FOREST_TRUST_RECORD_TYPE ForestTrustType; // type of record
|
|
#define TLN ForestTrustTopLevelName
|
|
#define TLNEX ForestTrustTopLevelNameEx
|
|
#define DOM ForestTrustDomainInfo
|
|
#define EOD (DOM+1)
|
|
LPWSTR Name;
|
|
PSID Sid;
|
|
LPWSTR NetbiosName;
|
|
} AN_ENTRY, *PAN_ENTRY;
|
|
|
|
//
|
|
// Define template FTinfo structures.
|
|
//
|
|
|
|
AN_ENTRY Ftinfo0[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo1[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, TLN, L"ms.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo2[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, TLN, L"z.au" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo3[] = {
|
|
{ 0, TLN, L"z.au" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo4[] = {
|
|
{ 0, TLN, L"corp.acme.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo5[] = {
|
|
{ 0, TLN, L"x.corp.acme.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo6[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ LSA_TLN_DISABLED_ADMIN, TLN, L"ms.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo7[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0xFFFFFFFF, TLN, L"ms.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo8[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ LSA_TLN_DISABLED_ADMIN, TLN, L"ms.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo9[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ LSA_TLN_DISABLED_ADMIN, TLN, L"b.a.ms.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo10[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, TLN, L"a.ms.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo11[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, TLNEX, L"a.acme.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
SID Sid1 = { 1, 1, SECURITY_NT_AUTHORITY, 1 };
|
|
SID Sid2 = { 1, 1, SECURITY_NT_AUTHORITY, 2 };
|
|
SID Sid3 = { 1, 1, SECURITY_NT_AUTHORITY, 3 };
|
|
SID Sid4 = { 1, 1, SECURITY_NT_AUTHORITY, 4 };
|
|
SID Sid5 = { 1, 1, SECURITY_NT_AUTHORITY, 5 };
|
|
|
|
AN_ENTRY Ftinfo12[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo13[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ LSA_SID_DISABLED_ADMIN, DOM, L"corp.acme.com", &Sid1, L"CORP_NB" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo13a[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0xFFFFFFFF, DOM, L"corp.acme.com", &Sid1, L"CORP_NB" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo14[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo15[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, TLN, L"a.acme.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo16[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, TLN, L"a.acme.com" },
|
|
{ 0, TLN, L"b.acme.com" },
|
|
{ 0, TLN, L"ms.com" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo17[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid3, L"CORP_NB2" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo18[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid1, L"CORP_NB2" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo19[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid1, L"CORP_NB2" },
|
|
{ 0, DOM, L"c3.corp.acme.com", &Sid1, L"CORP_NB3" },
|
|
{ 0, DOM, L"c4.corp.acme.com", &Sid1, L"CORP_NB4" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo20[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid3, L"CORP_NB2" },
|
|
{ 0, DOM, L"c3.corp.acme.com", &Sid4, L"CORP_NB3" },
|
|
{ 0, DOM, L"c4.corp.acme.com", &Sid5, L"CORP_NB4" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo21[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ LSA_SID_DISABLED_ADMIN, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid3, L"CORP_NB2" },
|
|
{ LSA_SID_DISABLED_ADMIN, DOM, L"c3.corp.acme.com", &Sid4, L"CORP_NB3" },
|
|
{ 0, DOM, L"c4.corp.acme.com", &Sid5, L"CORP_NB4" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo22[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ LSA_SID_DISABLED_ADMIN, DOM, L"ms.com", &Sid1, L"CORP_NB" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo23[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.ms.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.ms.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.ms.com", &Sid3, L"CORP_NB2" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo24[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid3, L"CORP_NB2" },
|
|
{ 0, DOM, L"c3.corp.acme.com", &Sid4, L"CORP_NB3" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo24a[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid3, L"CORP_NB2" },
|
|
{ 0, DOM, L"c3.corp.acme.com", &Sid4, L"CORP_NB3" },
|
|
{ LSA_NB_DISABLED_ADMIN, DOM, L"c4.corp.acme.com", &Sid5, L"CORP_NB4" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo24b[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid3, L"CORP_NB2" },
|
|
{ 0, DOM, L"c3.corp.acme.com", &Sid4, L"CORP_NB3" },
|
|
{ LSA_NB_DISABLED_CONFLICT, DOM, L"c4.corp.acme.com", &Sid5, L"CORP_NB4" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo24c[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid3, L"CORP_NB3" },
|
|
{ LSA_NB_DISABLED_ADMIN|LSA_NB_DISABLED_CONFLICT, DOM, L"c3.corp.acme.com", &Sid4, L"CORP_NB2" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
AN_ENTRY Ftinfo24d[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid3, L"CORP_NB3" },
|
|
{ 0xFFFFFFFF, DOM, L"c3.corp.acme.com", &Sid4, L"CORP_NB2" },
|
|
{ 0, EOD },
|
|
};
|
|
AN_ENTRY Ftinfo24e[] = {
|
|
{ 0, TLN, L"acme.com" },
|
|
{ 0, DOM, L"corp.acme.com", &Sid1, L"CORP_NB0" },
|
|
{ 0, DOM, L"c1.corp.acme.com", &Sid2, L"CORP_NB1" },
|
|
{ 0, DOM, L"c2.corp.acme.com", &Sid3, L"CORP_NB3" },
|
|
{ 0, DOM, L"c3.corp.acme.com", &Sid4, L"CORP_NB2" },
|
|
{ 0, EOD },
|
|
};
|
|
|
|
|
|
//
|
|
// Structure describine test cases
|
|
//
|
|
|
|
typedef struct _TEST_CASE {
|
|
PAN_ENTRY OldFtinfo;
|
|
#define PREVIOUS ((PAN_ENTRY) 1)
|
|
PAN_ENTRY NewFtinfo;
|
|
LPSTR Description;
|
|
} TEST_CASE, PTEST_CASE;
|
|
|
|
//
|
|
// Define the test cases
|
|
//
|
|
|
|
TEST_CASE TestCases[] = {
|
|
{ NULL, Ftinfo0, "Just acme.com TLN" },
|
|
{ NULL, Ftinfo1, "acme.com and ms.com TLN" },
|
|
{ NULL, Ftinfo2, "Same but switch the alphabetical order" },
|
|
{ NULL, Ftinfo3, "Have no TLN for the forest (Should fail w/ ERROR_INVALID_PARAMETER)" },
|
|
{ NULL, Ftinfo0, "Build acme.com again" },
|
|
{ PREVIOUS, Ftinfo1, "Add a new ms.com TLN" },
|
|
{ PREVIOUS, Ftinfo1, "Ensure the new bit doesn't go away" },
|
|
{ NULL, Ftinfo4, "Exact match on corp.acme.com TLN" },
|
|
{ NULL, Ftinfo5, "Only child of corp.acme.com TLN (Should fail w/ ERROR_INVALID_PARAMETER)" },
|
|
{ Ftinfo6, Ftinfo1, "Ensure a disabled TLN stays disabled" },
|
|
{ Ftinfo7, Ftinfo1, "Ensure all bits are preserved in a TLN" },
|
|
{ Ftinfo8, Ftinfo10, "Ensure a disabled TLN stays disabled in a child" },
|
|
{ Ftinfo9, Ftinfo10, "Ensure a disabled TLN does *not* disable a parent" },
|
|
{ NULL, Ftinfo11, "Ensure a TLNEX is ignored in new" },
|
|
{ Ftinfo11, Ftinfo0, "Ensure a TLNEX is copied from old" },
|
|
{ NULL, Ftinfo12, "Trivial single domain forest" },
|
|
{ Ftinfo13, Ftinfo12, "Ensure a disabled domain remains disabled" },
|
|
{ NULL, Ftinfo14, "Drop duplicate new TLN entries" },
|
|
{ NULL, Ftinfo15, "... even if the duplicate is subordinate" },
|
|
{ NULL, Ftinfo16, "... even if there are many of them" },
|
|
{ NULL, Ftinfo17, "Try multiple domain entries" },
|
|
{ NULL, Ftinfo18, "Duplicate Sids are bad" },
|
|
{ NULL, Ftinfo19, "... even if there are many of them" },
|
|
{ Ftinfo21, Ftinfo20, "Ensure multiple disabled domains remain disabled" },
|
|
{ Ftinfo13, Ftinfo0, "Don't let an old disabled domain entry go away" },
|
|
{ Ftinfo22, Ftinfo0, "... even if there's no TLN for the domain entry" },
|
|
{ Ftinfo17, Ftinfo20, "Add a new domain" },
|
|
{ Ftinfo20, Ftinfo17, "Delete old domains" },
|
|
{ NULL, Ftinfo23, "Ensure there's a TLN for every domain" },
|
|
{ Ftinfo13a,Ftinfo12, "Ensure all of the possible flag bits are preserved" },
|
|
{ Ftinfo24a,Ftinfo24, "Ensure that a netbios admin disabled bit doesn't disappear" },
|
|
{ Ftinfo24b,Ftinfo24, "... but that a netbios conflict does" },
|
|
{ Ftinfo24c,Ftinfo24, "... Get it right even if the NB entry moves to different sid" },
|
|
{ Ftinfo24d,Ftinfo24, "... and that all of the other flag bits stay put" },
|
|
{ PREVIOUS, Ftinfo24e,"... and that we self repait when the trusted domain stops lying" },
|
|
};
|
|
|
|
|
|
PLSA_FOREST_TRUST_INFORMATION
|
|
BuildFtinfo(
|
|
PAN_ENTRY AnEntry
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
|
|
Builds a FtInfo array from the "easy to initialize" templates.
|
|
|
|
Arguments:
|
|
|
|
AnEntry - Pointer to the first entry.
|
|
|
|
Return Value:
|
|
|
|
Returns a real ftinfo array.
|
|
If this weren't a cheesy test program, the caller should free this memory.
|
|
|
|
--*/
|
|
{
|
|
PAN_ENTRY CurrentEntry;
|
|
ULONG CurrentIndex;
|
|
PLSA_FOREST_TRUST_INFORMATION Ftinfo;
|
|
|
|
//
|
|
// NULL is OK
|
|
//
|
|
|
|
if ( AnEntry == NULL ) {
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Allocate the return array
|
|
//
|
|
|
|
Ftinfo = LocalAlloc( 0, sizeof(*Ftinfo) );
|
|
|
|
if ( Ftinfo == NULL ) {
|
|
printf( "No memory\n");
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Count the number of entries
|
|
//
|
|
|
|
Ftinfo->RecordCount = 0;
|
|
for ( CurrentEntry=AnEntry;
|
|
CurrentEntry->ForestTrustType != EOD;
|
|
CurrentEntry++ ) {
|
|
|
|
Ftinfo->RecordCount ++;
|
|
}
|
|
|
|
//
|
|
// Allocate the array of entry pointers.
|
|
//
|
|
|
|
Ftinfo->Entries = LocalAlloc( 0, sizeof(PLSA_FOREST_TRUST_RECORD) * Ftinfo->RecordCount );
|
|
|
|
if ( Ftinfo->Entries == NULL ) {
|
|
printf( "No memory\n");
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Loop through the entries.
|
|
//
|
|
|
|
CurrentIndex = 0;
|
|
for ( CurrentEntry=AnEntry;
|
|
CurrentEntry->ForestTrustType != EOD;
|
|
CurrentEntry++ ) {
|
|
|
|
//
|
|
// Allocate the entry
|
|
//
|
|
|
|
Ftinfo->Entries[CurrentIndex] = LocalAlloc( LMEM_ZEROINIT, sizeof(LSA_FOREST_TRUST_RECORD) );
|
|
|
|
if ( Ftinfo->Entries[CurrentIndex] == NULL ) {
|
|
printf( "No memory\n");
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Fill it in
|
|
//
|
|
|
|
Ftinfo->Entries[CurrentIndex]->ForestTrustType = CurrentEntry->ForestTrustType;
|
|
Ftinfo->Entries[CurrentIndex]->Flags = CurrentEntry->Flags;
|
|
|
|
switch ( CurrentEntry->ForestTrustType ) {
|
|
case TLN:
|
|
case TLNEX:
|
|
RtlInitUnicodeString(
|
|
&Ftinfo->Entries[CurrentIndex]->ForestTrustData.TopLevelName,
|
|
CurrentEntry->Name );
|
|
break;
|
|
case DOM:
|
|
RtlInitUnicodeString(
|
|
&Ftinfo->Entries[CurrentIndex]->ForestTrustData.DomainInfo.DnsName,
|
|
CurrentEntry->Name );
|
|
|
|
Ftinfo->Entries[CurrentIndex]->ForestTrustData.DomainInfo.Sid =
|
|
CurrentEntry->Sid;
|
|
|
|
RtlInitUnicodeString(
|
|
&Ftinfo->Entries[CurrentIndex]->ForestTrustData.DomainInfo.NetbiosName,
|
|
CurrentEntry->NetbiosName );
|
|
break;
|
|
default:
|
|
printf( "Bad forest trust type\n");
|
|
return NULL;
|
|
}
|
|
|
|
CurrentIndex ++;
|
|
}
|
|
|
|
return Ftinfo;
|
|
}
|
|
|
|
|
|
|
|
|
|
int __cdecl
|
|
main (
|
|
IN int argc,
|
|
IN char ** argv
|
|
)
|
|
{
|
|
NET_API_STATUS NetStatus;
|
|
PLSA_FOREST_TRUST_INFORMATION OldFtinfo;
|
|
PLSA_FOREST_TRUST_INFORMATION NewFtinfo;
|
|
PLSA_FOREST_TRUST_INFORMATION OutputFtinfo = NULL;
|
|
ULONG CaseIndex;
|
|
ULONG FirstIndex = 0;
|
|
|
|
//
|
|
// If an argument is specified,
|
|
// it is the test number to start with.
|
|
//
|
|
|
|
if ( argc > 1 ) {
|
|
char *end;
|
|
FirstIndex = strtoul( argv[1], &end, 10 );
|
|
}
|
|
|
|
//
|
|
// Loop through the list of tests
|
|
//
|
|
|
|
for ( CaseIndex=FirstIndex; CaseIndex<(sizeof(TestCases)/sizeof(TestCases[0])); CaseIndex++ ) {
|
|
|
|
|
|
printf( "\nCase %ld: %s\n", CaseIndex, TestCases[CaseIndex].Description );
|
|
|
|
//
|
|
// Build the test case FTINFO structures
|
|
//
|
|
|
|
if ( TestCases[CaseIndex].OldFtinfo == PREVIOUS ) {
|
|
OldFtinfo = OutputFtinfo;
|
|
} else {
|
|
OldFtinfo = BuildFtinfo( TestCases[CaseIndex].OldFtinfo );
|
|
}
|
|
|
|
NewFtinfo = BuildFtinfo( TestCases[CaseIndex].NewFtinfo );
|
|
|
|
//
|
|
// Display them
|
|
//
|
|
|
|
printf(" Old Ftinfo:\n");
|
|
DumpFtinfo( OldFtinfo );
|
|
|
|
printf(" New Ftinfo:\n");
|
|
DumpFtinfo( NewFtinfo );
|
|
|
|
//
|
|
// Merge them
|
|
//
|
|
|
|
NetStatus = DsMergeForestTrustInformationW( L"corp.acme.com",
|
|
NewFtinfo,
|
|
OldFtinfo,
|
|
&OutputFtinfo );
|
|
|
|
if ( NetStatus != NERR_Success ) {
|
|
printf( "DsMergeForestTrustInformationW failed: ");
|
|
PrintStatus( NetStatus );
|
|
} else {
|
|
printf(" Result Ftinfo:\n");
|
|
DumpFtinfo( OutputFtinfo );
|
|
}
|
|
|
|
}
|
|
|
|
printf("\n\nYee haw. We're done.\n");
|
|
return 0;
|
|
|
|
}
|