525 lines
11 KiB
C
525 lines
11 KiB
C
/*--
|
||
|
||
Copyright (c) 1993 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
nltest.c
|
||
|
||
Abstract:
|
||
|
||
Test program for the Netlogon service.
|
||
|
||
Author:
|
||
|
||
21-Apr-1993 (madana)
|
||
|
||
Environment:
|
||
|
||
User mode only.
|
||
Contains NT-specific code.
|
||
Requires ANSI C extensions: slash-slash comments, long external names.
|
||
|
||
Revision History:
|
||
|
||
--*/
|
||
|
||
|
||
//
|
||
// Common include files.
|
||
//
|
||
|
||
#include <logonsrv.h> // Include files common to entire service
|
||
#include <stdio.h>
|
||
#include <string.h>
|
||
#include <align.h>
|
||
|
||
//
|
||
// delta entry in the list
|
||
//
|
||
|
||
typedef struct _DELTA_ENTRY {
|
||
LIST_ENTRY Next;
|
||
PCHANGELOG_ENTRY ChangeLogEntry;
|
||
DWORD Order;
|
||
} DELTA_ENTRY, *PDELTA_ENTRY;
|
||
|
||
|
||
LIST_ENTRY GlobalDeltaLists[NUM_DBS + 1];
|
||
// list of deltas, include VOID DB also.
|
||
|
||
//
|
||
// Externals needed by chutil.obj
|
||
|
||
CRITICAL_SECTION NlGlobalChangeLogCritSect;
|
||
CHANGELOG_DESCRIPTOR NlGlobalChangeLogDesc;
|
||
CHANGELOG_DESCRIPTOR NlGlobalTempChangeLogDesc;
|
||
CHANGELOG_ROLE NlGlobalChangeLogRole;
|
||
WCHAR NlGlobalChangeLogFilePrefix[MAX_PATH+1];
|
||
LARGE_INTEGER NlGlobalChangeLogPromotionIncrement = DOMAIN_PROMOTION_INCREMENT;
|
||
LARGE_INTEGER PromotionMask = DOMAIN_PROMOTION_MASK;
|
||
LONG NlGlobalChangeLogPromotionMask;
|
||
|
||
//
|
||
// Stub routines needed by chutil.obj
|
||
//
|
||
|
||
VOID
|
||
NlpWriteEventlog (
|
||
IN DWORD EventID,
|
||
IN DWORD EventType,
|
||
IN LPBYTE RawDataBuffer OPTIONAL,
|
||
IN DWORD RawDataSize,
|
||
IN LPWSTR *StringArray,
|
||
IN DWORD StringCount
|
||
)
|
||
{
|
||
return;
|
||
UNREFERENCED_PARAMETER( EventID );
|
||
UNREFERENCED_PARAMETER( EventType );
|
||
UNREFERENCED_PARAMETER( RawDataBuffer );
|
||
UNREFERENCED_PARAMETER( RawDataSize );
|
||
UNREFERENCED_PARAMETER( StringArray );
|
||
UNREFERENCED_PARAMETER( StringCount );
|
||
}
|
||
|
||
|
||
VOID
|
||
MakeDeltaLists(
|
||
VOID
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine make list of deltas of individual databases.
|
||
|
||
Arguments:
|
||
|
||
None
|
||
|
||
Return Value:
|
||
|
||
none.
|
||
|
||
--*/
|
||
{
|
||
|
||
PCHANGELOG_ENTRY ChangeLogEntry;
|
||
DWORD j;
|
||
DWORD Order = 1;
|
||
|
||
//
|
||
// initialize list enties.
|
||
//
|
||
|
||
for( j = 0; j < NUM_DBS + 1; j++ ) {
|
||
InitializeListHead(&GlobalDeltaLists[j]);
|
||
}
|
||
|
||
//
|
||
// The cache is valid if it is empty.
|
||
//
|
||
|
||
if ( ChangeLogIsEmpty( &NlGlobalChangeLogDesc) ) {
|
||
return;
|
||
}
|
||
|
||
ChangeLogEntry = (PCHANGELOG_ENTRY)(NlGlobalChangeLogDesc.Head+1);
|
||
do {
|
||
|
||
PDELTA_ENTRY NewDelta;
|
||
|
||
//
|
||
// make delta entry to insert in the list
|
||
//
|
||
|
||
NewDelta = (PDELTA_ENTRY)NetpMemoryAllocate( sizeof(DELTA_ENTRY) );
|
||
|
||
if ( NewDelta == NULL ) {
|
||
fprintf( stderr, "Not enough memory\n" );
|
||
return;
|
||
}
|
||
|
||
NewDelta->ChangeLogEntry = ChangeLogEntry;
|
||
NewDelta->Order = Order++;
|
||
|
||
//
|
||
// add this entry to appropriate list.
|
||
//
|
||
|
||
InsertTailList( &GlobalDeltaLists[ChangeLogEntry->DBIndex],
|
||
&NewDelta->Next );
|
||
|
||
|
||
} while ( ( ChangeLogEntry =
|
||
NlMoveToNextChangeLogEntry(&NlGlobalChangeLogDesc, ChangeLogEntry) ) != NULL );
|
||
|
||
return;
|
||
|
||
}
|
||
|
||
#if !NETLOGONDBG
|
||
// This routine is defined in chutil.obj for the debug version
|
||
|
||
VOID
|
||
PrintChangeLogEntry(
|
||
PCHANGELOG_ENTRY ChangeLogEntry
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine print the content of the given changelog entry.
|
||
|
||
Arguments:
|
||
|
||
ChangeLogEntry -- pointer to the change log entry to print
|
||
|
||
Return Value:
|
||
|
||
none.
|
||
|
||
--*/
|
||
{
|
||
LPSTR DeltaName;
|
||
|
||
switch ( ChangeLogEntry->DeltaType ) {
|
||
case AddOrChangeDomain:
|
||
DeltaName = "AddOrChangeDomain";
|
||
break;
|
||
case AddOrChangeGroup:
|
||
DeltaName = "AddOrChangeGroup";
|
||
break;
|
||
case DeleteGroupByName:
|
||
case DeleteGroup:
|
||
DeltaName = "DeleteGroup";
|
||
break;
|
||
case RenameGroup:
|
||
DeltaName = "RenameGroup";
|
||
break;
|
||
case AddOrChangeUser:
|
||
DeltaName = "AddOrChangeUser";
|
||
break;
|
||
case DeleteUserByName:
|
||
case DeleteUser:
|
||
DeltaName = "DeleteUser";
|
||
break;
|
||
case RenameUser:
|
||
DeltaName = "RenameUser";
|
||
break;
|
||
case ChangeGroupMembership:
|
||
DeltaName = "ChangeGroupMembership";
|
||
break;
|
||
case AddOrChangeAlias:
|
||
DeltaName = "AddOrChangeAlias";
|
||
break;
|
||
case DeleteAlias:
|
||
DeltaName = "DeleteAlias";
|
||
break;
|
||
case RenameAlias:
|
||
DeltaName = "RenameAlias";
|
||
break;
|
||
case ChangeAliasMembership:
|
||
DeltaName = "ChangeAliasMembership";
|
||
break;
|
||
case AddOrChangeLsaPolicy:
|
||
DeltaName = "AddOrChangeLsaPolicy";
|
||
break;
|
||
case AddOrChangeLsaTDomain:
|
||
DeltaName = "AddOrChangeLsaTDomain";
|
||
break;
|
||
case DeleteLsaTDomain:
|
||
DeltaName = "DeleteLsaTDomain";
|
||
break;
|
||
case AddOrChangeLsaAccount:
|
||
DeltaName = "AddOrChangeLsaAccount";
|
||
break;
|
||
case DeleteLsaAccount:
|
||
DeltaName = "DeleteLsaAccount";
|
||
break;
|
||
case AddOrChangeLsaSecret:
|
||
DeltaName = "AddOrChangeLsaSecret";
|
||
break;
|
||
case DeleteLsaSecret:
|
||
DeltaName = "DeleteLsaSecret";
|
||
break;
|
||
case SerialNumberSkip:
|
||
DeltaName = "SerialNumberSkip";
|
||
break;
|
||
case DummyChangeLogEntry:
|
||
DeltaName = "DummyChangeLogEntry";
|
||
break;
|
||
|
||
default:
|
||
DeltaName ="(Unknown)";
|
||
break;
|
||
}
|
||
|
||
NlPrint((NL_CHANGELOG,
|
||
"DeltaType %s (%ld) SerialNumber: %lx %lx",
|
||
DeltaName,
|
||
ChangeLogEntry->DeltaType,
|
||
ChangeLogEntry->SerialNumber.HighPart,
|
||
ChangeLogEntry->SerialNumber.LowPart ));
|
||
|
||
if ( ChangeLogEntry->ObjectRid != 0 ) {
|
||
NlPrint((NL_CHANGELOG," Rid: 0x%lx", ChangeLogEntry->ObjectRid ));
|
||
}
|
||
if ( ChangeLogEntry->Flags & CHANGELOG_REPLICATE_IMMEDIATELY ) {
|
||
NlPrint((NL_CHANGELOG," Immediately" ));
|
||
}
|
||
if ( ChangeLogEntry->Flags & CHANGELOG_PDC_PROMOTION ) {
|
||
NlPrint((NL_CHANGELOG," Promotion" ));
|
||
}
|
||
if ( ChangeLogEntry->Flags & CHANGELOG_PASSWORD_CHANGE ) {
|
||
NlPrint((NL_CHANGELOG," PasswordChanged" ));
|
||
}
|
||
|
||
|
||
if( ChangeLogEntry->Flags & CHANGELOG_NAME_SPECIFIED ) {
|
||
NlPrint(( NL_CHANGELOG, " Name: '" FORMAT_LPWSTR "'",
|
||
(LPWSTR)((PBYTE)(ChangeLogEntry)+ sizeof(CHANGELOG_ENTRY))));
|
||
}
|
||
|
||
if( ChangeLogEntry->Flags & CHANGELOG_SID_SPECIFIED ) {
|
||
NlPrint((NL_CHANGELOG," Sid: "));
|
||
NlpDumpSid( NL_CHANGELOG,
|
||
(PSID)((PBYTE)(ChangeLogEntry)+ sizeof(CHANGELOG_ENTRY)) );
|
||
} else {
|
||
NlPrint((NL_CHANGELOG,"\n" ));
|
||
}
|
||
}
|
||
#endif // NETLOGONDBG
|
||
|
||
|
||
VOID
|
||
PrintDelta(
|
||
PDELTA_ENTRY Delta
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine print the content of the given delta.
|
||
|
||
Arguments:
|
||
|
||
Delta: pointer to a delta entry to be printed.
|
||
|
||
Return Value:
|
||
|
||
none.
|
||
|
||
--*/
|
||
{
|
||
printf( "Order: %ld ", Delta->Order );
|
||
PrintChangeLogEntry( Delta->ChangeLogEntry );
|
||
}
|
||
|
||
|
||
VOID
|
||
PrintDeltaLists(
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This routine prints deltas of individual databases and validates the
|
||
sequence.
|
||
|
||
Arguments:
|
||
|
||
none.
|
||
|
||
Return Value:
|
||
|
||
none.
|
||
|
||
--*/
|
||
{
|
||
|
||
DWORD j;
|
||
LARGE_INTEGER RunningChangeLogSerialNumber[NUM_DBS+1];
|
||
|
||
for( j = 0; j < NUM_DBS + 1; j++ ) {
|
||
RunningChangeLogSerialNumber[j].QuadPart = 0;
|
||
}
|
||
|
||
//
|
||
// for each database.
|
||
//
|
||
for( j = 0; j < NUM_DBS + 1; j++ ) {
|
||
|
||
if( j == SAM_DB ) {
|
||
printf("Deltas of SAM DATABASE \n\n" );
|
||
} else if( j == BUILTIN_DB ) {
|
||
printf("Deltas of BUILTIN DATABASE \n\n" );
|
||
} else if( j == LSA_DB ) {
|
||
printf("Deltas of LSA DATABASE \n\n" );
|
||
} else if( j == VOID_DB ) {
|
||
printf("VOID Deltas \n\n" );
|
||
}
|
||
|
||
while( !IsListEmpty( &GlobalDeltaLists[j] ) ) {
|
||
|
||
PDELTA_ENTRY NextDelta;
|
||
PCHANGELOG_ENTRY ChangeLogEntry;
|
||
|
||
NextDelta = (PDELTA_ENTRY)
|
||
RemoveHeadList( &GlobalDeltaLists[j] );
|
||
|
||
ChangeLogEntry = NextDelta->ChangeLogEntry;
|
||
|
||
//
|
||
// validate this delta.
|
||
//
|
||
|
||
if ( RunningChangeLogSerialNumber[j].QuadPart == 0 ) {
|
||
|
||
//
|
||
// first entry for this database
|
||
//
|
||
// Increment to next expected serial number
|
||
//
|
||
|
||
RunningChangeLogSerialNumber[j].QuadPart =
|
||
ChangeLogEntry->SerialNumber.QuadPart + 1;
|
||
|
||
|
||
//
|
||
// Otherwise ensure the serial number is the value expected.
|
||
//
|
||
|
||
} else {
|
||
|
||
|
||
//
|
||
// If the order is wrong,
|
||
// just report the problem.
|
||
//
|
||
|
||
if ( !IsSerialNumberEqual(
|
||
&NlGlobalChangeLogDesc,
|
||
ChangeLogEntry,
|
||
&RunningChangeLogSerialNumber[j] ) ) {
|
||
|
||
if ( j != NUM_DBS ) {
|
||
printf("*** THIS ENTRY IS OUT OF SEQUENCE *** \n");
|
||
}
|
||
|
||
}
|
||
|
||
RunningChangeLogSerialNumber[j].QuadPart =
|
||
ChangeLogEntry->SerialNumber.QuadPart + 1;
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// print delta
|
||
//
|
||
|
||
PrintDelta( NextDelta );
|
||
|
||
//
|
||
// free this entry.
|
||
//
|
||
|
||
NetpMemoryFree( NextDelta );
|
||
|
||
}
|
||
|
||
printf("-----------------------------------------------\n");
|
||
}
|
||
|
||
}
|
||
|
||
VOID
|
||
ListDeltas(
|
||
LPWSTR DeltaFileName
|
||
)
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
This function prints out the content of the change log file in
|
||
readable format. Also it also checks the consistency of the change
|
||
log. If not, it will point out the inconsistency.
|
||
|
||
Arguments:
|
||
|
||
DeltaFileName - name of the change log file.
|
||
|
||
Return Value:
|
||
|
||
none.
|
||
|
||
--*/
|
||
{
|
||
NTSTATUS Status;
|
||
|
||
// Needed by routines in chutil.obj
|
||
try {
|
||
InitializeCriticalSection( &NlGlobalChangeLogCritSect );
|
||
} except( EXCEPTION_EXECUTE_HANDLER ) {
|
||
fprintf( stderr, "Cannot initialize NlGlobalChangeLogCritSect\n" );
|
||
goto Cleanup;
|
||
}
|
||
NlGlobalChangeLogPromotionMask = PromotionMask.HighPart;
|
||
InitChangeLogDesc( &NlGlobalChangeLogDesc );
|
||
|
||
//
|
||
// Read in the existing changelog file.
|
||
//
|
||
|
||
Status = NlOpenChangeLogFile( DeltaFileName, &NlGlobalChangeLogDesc, TRUE );
|
||
|
||
if ( !NT_SUCCESS(Status) ) {
|
||
|
||
fprintf( stderr, "Couldn't NlOpenChangeLogFile'" FORMAT_LPWSTR
|
||
"': 0x%lx \n",
|
||
DeltaFileName,
|
||
Status );
|
||
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// Write to this file if conversion needed.
|
||
//
|
||
if ( NlGlobalChangeLogDesc.Version3 ) {
|
||
printf( "Converting version 3 changelog to version 4 -- writing netlv40.chg\n");
|
||
wcscpy( NlGlobalChangeLogFilePrefix, L"netlv40" );
|
||
}
|
||
|
||
//
|
||
// Convert the changelog file to the right size/version.
|
||
//
|
||
|
||
Status = NlResizeChangeLogFile( &NlGlobalChangeLogDesc, NlGlobalChangeLogDesc.BufferSize );
|
||
|
||
if ( !NT_SUCCESS(Status) ) {
|
||
|
||
fprintf( stderr, "Couldn't NlOpenChangeLogFile'" FORMAT_LPWSTR
|
||
"': 0x%lx \n",
|
||
DeltaFileName,
|
||
Status );
|
||
|
||
goto Cleanup;
|
||
}
|
||
|
||
//
|
||
// print change log signature
|
||
|
||
printf( "FILE SIGNATURE : %s \n\n", NlGlobalChangeLogDesc.Buffer );
|
||
|
||
MakeDeltaLists();
|
||
|
||
PrintDeltaLists();
|
||
|
||
Cleanup:
|
||
|
||
return;
|
||
}
|