|
|
//++
//
// Copyright (C) Microsoft Corporation, 1987 - 1999
//
// Module Name:
//
// dsgetdc.c
//
// Abstract:
//
// Queries into network drivers
//
// Author:
//
// Anilth - 4-20-1998
//
// Environment:
//
// User mode only.
// Contains NT-specific code.
//
// Revision History:
//
//--
#include "precomp.h"
#include "objbase.h"
VOID PrintDsGetDcName(IN NETDIAG_RESULT *pResults, IN OUT PLIST_ENTRY plmsgOutput, IN PDOMAIN_CONTROLLER_INFOW DomainControllerInfo);
NET_API_STATUS SetPrimaryGuid(IN GUID *GuidToSet);
HRESULT DsGetDcTest(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults) /*++
Routine Description:
Ensure that we can find domain controllers
Arguments:
None.
Return Value:
TRUE: Test suceeded. FALSE: Test failed
--*/ { NET_API_STATUS NetStatus; NET_API_STATUS LocalNetStatus; BOOL RetVal = TRUE; HRESULT hr = hrOK; LPTSTR pszDcType; PTESTED_DOMAIN pTestedDomain = (PTESTED_DOMAIN) pParams->pDomain; PDOMAIN_CONTROLLER_INFOW LocalDomainControllerInfo = NULL;
//if the machine is a member machine or DC, DsGetDc Test will get called.
//Otherwise, this test will be skipped
pResults->DsGetDc.fPerformed = TRUE;
//the DsGetDc test will be called for every domain, but we only want to initialize
//the message list once.
if(pResults->DsGetDc.lmsgOutput.Flink == NULL) InitializeListHead(&pResults->DsGetDc.lmsgOutput); PrintStatusMessage(pParams, 4, IDS_DSGETDC_STATUS_MSG);
//
// Find a generic DC
//
PrintStatusMessage(pParams, 4, IDS_DSGETDC_STATUS_DC);
pszDcType = LoadAndAllocString(IDS_DCTYPE_DC); NetStatus = DoDsGetDcName( pParams, pResults, &pResults->DsGetDc.lmsgOutput, pTestedDomain, DS_DIRECTORY_SERVICE_PREFERRED, pszDcType, //_T("DC"),
TRUE, &pTestedDomain->DcInfo ); Free(pszDcType); pTestedDomain->fTriedToFindDcInfo = TRUE;
if ( NetStatus != NO_ERROR ) { hr = S_FALSE; goto Error; } //
// Find a PDC
// (Failure isn't fatal.)
//
PrintStatusMessage(pParams, 4, IDS_DSGETDC_STATUS_PDC);
pszDcType = LoadAndAllocString(IDS_DCTYPE_PDC); LocalNetStatus = DoDsGetDcName(pParams, pResults, &pResults->DsGetDc.lmsgOutput, pTestedDomain, DS_PDC_REQUIRED, pszDcType, //_T("PDC"),
FALSE, &LocalDomainControllerInfo ); Free(pszDcType); if ( LocalNetStatus == NO_ERROR ) { if ( LocalDomainControllerInfo != NULL ) { NetApiBufferFree( LocalDomainControllerInfo ); LocalDomainControllerInfo = NULL; } } //
// Find an NT 5 DC
// (Failure isn't fatal.)
//
PrintStatusMessage(pParams, 4, IDS_DSGETDC_STATUS_NT5DC); pszDcType = LoadAndAllocString(IDS_DCTYPE_W2K_DC); LocalNetStatus = DoDsGetDcName(pParams, pResults, &pResults->DsGetDc.lmsgOutput, pTestedDomain, DS_DIRECTORY_SERVICE_REQUIRED, pszDcType, //_T("Windows 2000 DC"),
FALSE, &LocalDomainControllerInfo ); Free(pszDcType); if ( LocalNetStatus == NO_ERROR ) { if ( LocalDomainControllerInfo != NULL ) { NetApiBufferFree( LocalDomainControllerInfo ); LocalDomainControllerInfo = NULL; } } //
// Ensure the returned domain GUID is the domain GUID stored in the LSA
//
if ( pTestedDomain == pResults->Global.pMemberDomain ) { if ( !IsEqualGUID( &pResults->Global.pPrimaryDomainInfo->DomainGuid, &NlDcZeroGuid ) && !IsEqualGUID( &pTestedDomain->DcInfo->DomainGuid, &NlDcZeroGuid ) && !IsEqualGUID( &pResults->Global.pPrimaryDomainInfo->DomainGuid, &pTestedDomain->DcInfo->DomainGuid ) ) { // Need to convert the two GUIDS
WCHAR swzGuid1[64]; WCHAR swzGuid2[64];
StringFromGUID2(&pResults->Global.pPrimaryDomainInfo->DomainGuid, swzGuid1, DimensionOf(swzGuid1)); StringFromGUID2(&pTestedDomain->DcInfo->DomainGuid, swzGuid2, DimensionOf(swzGuid2));
// " [FATAL] Your machine thinks the domain GUID of domain '%ws' is\n '"
// "' but \n '%ws' thinks it is\n '"
AddMessageToList(&pResults->DsGetDc.lmsgOutput, Nd_Quiet, IDS_DSGETDC_FATAL_GUID, pResults->Global.pPrimaryDomainInfo->DomainNameFlat, swzGuid1, pTestedDomain->DcInfo->DomainControllerName, swzGuid2);
hr = S_FALSE; //
// Attempt to fix the problem.
//
if ( !pParams->fFixProblems ) { // "\nConsider running 'nettest /fix' to try to fix this problem\n"
AddMessageToList( &pResults->DsGetDc.lmsgOutput, Nd_Quiet, IDS_DSGETDC_13206 ); } else { NetStatus = SetPrimaryGuid( &pTestedDomain->DcInfo->DomainGuid ); if ( NetStatus != NO_ERROR ) { if ( NetStatus == ERROR_ACCESS_DENIED ) { // "\nCannot fix domain GUID since you are not an administrator. Leave then rejoin the domain.\n"
AddMessageToList( &pResults->DsGetDc.lmsgOutput, Nd_Quiet, IDS_DSGETDC_13207 ); } else { // " [FATAL] Failed to fix Domain Guid. [%s]\n"
AddMessageToList( &pResults->DsGetDc.lmsgOutput, Nd_Quiet, IDS_DSGETDC_13208, NetStatusToString(NetStatus) ); } } else { // "\nFixed domain GUID. Reboot then run 'nettest' again to ensure everything is working.\n"
AddMessageToList( &pResults->DsGetDc.lmsgOutput, Nd_Quiet, IDS_DSGETDC_13209 ); } } } } Error: //$REVIEW (nsun 10/05/98) CliffV deleted DCNameClose()
//DCNameClose();
pResults->DsGetDc.hr = hr; return hr; }
VOID PrintDsGetDcName( IN NETDIAG_RESULT *pResults, IN OUT PLIST_ENTRY plmsgOutput, IN PDOMAIN_CONTROLLER_INFOW DomainControllerInfo ) /*++
Routine Description:
Prints the information returned from DsGetDcName
Arguments:
DomainControllerInfo - Information to print
Return Value:
None.
--*/ { // " DC: %ws\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13210, DomainControllerInfo->DomainControllerName ); // " Address: %ws\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13211, DomainControllerInfo->DomainControllerAddress );
if ( !IsEqualGUID( &DomainControllerInfo->DomainGuid, &NlDcZeroGuid) ) { WCHAR swzGuid[64]; StringFromGUID2(&DomainControllerInfo->DomainGuid, swzGuid, DimensionOf(swzGuid)); // " Domain Guid . . . . . . : %ws\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13212, swzGuid); }
if ( DomainControllerInfo->DomainName != NULL ) { // " Dom Name: %ws\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13214, DomainControllerInfo->DomainName ); } if ( DomainControllerInfo->DnsForestName != NULL ) { // " Forest Name: %ws\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13215, DomainControllerInfo->DnsForestName ); } if ( DomainControllerInfo->DcSiteName != NULL ) { // " Dc Site Name: %ws\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13216, DomainControllerInfo->DcSiteName ); } if ( DomainControllerInfo->ClientSiteName != NULL ) { // " Our Site Name: %ws\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13217, DomainControllerInfo->ClientSiteName ); } if ( DomainControllerInfo->Flags ) { ULONG LocalFlags = DomainControllerInfo->Flags; // " Flags:"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13218 ); if ( LocalFlags & DS_PDC_FLAG ) { // " PDC"
AddMessageToList( plmsgOutput, Nd_Quiet, (LocalFlags & DS_DS_FLAG) ? IDS_DSGETDC_13219 : IDS_DSGETDC_NT4_PDC); LocalFlags &= ~DS_PDC_FLAG; } if ( LocalFlags & DS_GC_FLAG ) { //IDS_DSGETDC_13220 " GC"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13220); LocalFlags &= ~DS_GC_FLAG; } if ( LocalFlags & DS_DS_FLAG ) { //IDS_DSGETDC_13221 " DS"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13221); LocalFlags &= ~DS_DS_FLAG; } if ( LocalFlags & DS_KDC_FLAG ) { //IDS_DSGETDC_13222 " KDC"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13222); LocalFlags &= ~DS_KDC_FLAG; } if ( LocalFlags & DS_TIMESERV_FLAG ) { //IDS_DSGETDC_13223 " TIMESERV"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13223); LocalFlags &= ~DS_TIMESERV_FLAG; } if ( LocalFlags & DS_GOOD_TIMESERV_FLAG ) { //IDS_DSGETDC_13224 " GTIMESERV"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13224); LocalFlags &= ~DS_GOOD_TIMESERV_FLAG; } if ( LocalFlags & DS_WRITABLE_FLAG ) { //IDS_DSGETDC_13225 " WRITABLE"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13225); LocalFlags &= ~DS_WRITABLE_FLAG; } if ( LocalFlags & DS_DNS_CONTROLLER_FLAG ) { //IDS_DSGETDC_13226 " DNS_DC"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13226); LocalFlags &= ~DS_DNS_CONTROLLER_FLAG; } if ( LocalFlags & DS_DNS_DOMAIN_FLAG ) { //IDS_DSGETDC_13227 " DNS_DOMAIN"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13227); LocalFlags &= ~DS_DNS_DOMAIN_FLAG; } if ( LocalFlags & DS_DNS_FOREST_FLAG ) { //IDS_DSGETDC_13228 " DNS_FOREST"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13228); LocalFlags &= ~DS_DNS_FOREST_FLAG; } if ( LocalFlags & DS_CLOSEST_FLAG ) { //IDS_DSGETDC_13229 " CLOSE_SITE"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13229); LocalFlags &= ~DS_CLOSEST_FLAG; } if ( LocalFlags != 0 ) { //IDS_DSGETDC_13230 " 0x%lX"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13230, LocalFlags); } //IDS_DSGETDC_13231 "\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13231); } }
NET_API_STATUS DoDsGetDcName(IN NETDIAG_PARAMS *pParams, IN OUT NETDIAG_RESULT *pResults, OUT PLIST_ENTRY plmsgOutput, IN PTESTED_DOMAIN pTestedDomain, IN DWORD Flags, IN LPTSTR pszDcType, IN BOOLEAN IsFatal, OUT PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo ) /*++
Routine Description:
Does a DsGetDcName
Arguments:
plmsgOutput - The message list to dump output pTestedDomain - Domain to test
Flags - Flags to pass to DsGetDcName
pszDcType - English description of Flags
IsFatal - True if failure is fatal
DomainControllerInfo - Return Domain Controller information
Return Value:
Status of the operation.
--*/ { NET_API_STATUS NetStatus; PDOMAIN_CONTROLLER_INFOW LocalDomainControllerInfo = NULL; LPSTR Severity;
//
// Initialization
//
if ( IsFatal ) { Severity = "[FATAL]"; } else { Severity = "[WARNING]"; } if ( pParams->fReallyVerbose ) { // "\n Find %s in domain '%ws':\n"
AddMessageToList( plmsgOutput, Nd_ReallyVerbose, IDS_DSGETDC_13232, pszDcType, pTestedDomain->PrintableDomainName ); }
//
// Find a DC in the domain.
// Use the DsGetDcName built into nettest.
//
NetStatus = GetADc( pParams, pResults, plmsgOutput, // Commented out to port to Source Depot - smanda
#ifdef SLM_TREE
NettestDsGetDcNameW, #else
DsGetDcNameW, #endif
pTestedDomain, Flags, DomainControllerInfo );
if ( NetStatus != NO_ERROR ) { // " %s Cannot find %s in domain '%ws'. [%s]\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13233, Severity, pszDcType, pTestedDomain->PrintableDomainName, NetStatusToString(NetStatus)); if ( NetStatus == ERROR_NO_SUCH_DOMAIN ) { if ( Flags & DS_DIRECTORY_SERVICE_REQUIRED ) { // "\n This isn't a problem if domain '%ws' does not have any NT 5.0 DCs.\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13234, pTestedDomain->PrintableDomainName ); } else if ( Flags & DS_PDC_REQUIRED ) { PrintGuruMessage2(" If the PDC for domain '%ws' is up, ", TestedDomain->PrintableDomainName ); PrintGuru( 0, DSGETDC_GURU ); } else { PrintGuruMessage3(" If any %s for domain '%ws' is up, ", DcType, TestedDomain->PrintableDomainName ); PrintGuru( 0, DSGETDC_GURU ); } } else { PrintGuru( NetStatus, DSGETDC_GURU ); }
//
// If that worked,
// try again through netlogon this time.
//
} else {
if (pParams->fReallyVerbose ) { // " Found this %s in domain '%ws':\n"
AddMessageToList( plmsgOutput, Nd_ReallyVerbose, IDS_DSGETDC_13235, pszDcType, pTestedDomain->PrintableDomainName ); PrintDsGetDcName( pResults, plmsgOutput, *DomainControllerInfo ); } else if ( pParams->fVerbose ) { // " Found %s '%ws' in domain '%ws'.\n"
AddMessageToList( plmsgOutput, Nd_Verbose, IDS_DSGETDC_13236, pszDcType, (*DomainControllerInfo)->DomainControllerName, pTestedDomain->PrintableDomainName ); }
if ( ((*DomainControllerInfo)->Flags & (DS_DS_FLAG|DS_KDC_FLAG)) == DS_DS_FLAG ) { // " %s: KDC is not running on NT 5 DC '%ws' in domain '%ws'."
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13237, Severity, (*DomainControllerInfo)->DomainControllerName, pTestedDomain->PrintableDomainName ); }
//
// If netlogon is running,
// try it again using the netlogon service.
//
if ( pResults->Global.fNetlogonIsRunning ) {
NetStatus = GetADc( pParams, pResults, plmsgOutput, DsGetDcNameW, pTestedDomain, Flags, &LocalDomainControllerInfo );
if ( NetStatus != NO_ERROR ) { // " %s: Netlogon cannot find %s in domain '%ws'. [%s]\n"
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13238, Severity, pszDcType, pTestedDomain->PrintableDomainName, NetStatusToString(NetStatus));
//
// If that worked,
// sanity check the returned DC.
//
} else {
if ( (LocalDomainControllerInfo->Flags & (DS_DS_FLAG|DS_KDC_FLAG)) == DS_DS_FLAG ) { // " %s: KDC is not running on NT 5 DC '%ws' in domain '%ws'."
AddMessageToList( plmsgOutput, Nd_Quiet, IDS_DSGETDC_13239, Severity, LocalDomainControllerInfo->DomainControllerName, pTestedDomain->PrintableDomainName ); } } } }
if ( LocalDomainControllerInfo != NULL ) { NetApiBufferFree( LocalDomainControllerInfo ); LocalDomainControllerInfo = NULL; }
return NetStatus; }
NET_API_STATUS SetPrimaryGuid( IN GUID *GuidToSet ) /*++
Routine Description:
Set the primary GUID to the specified value.
Arguments:
GuidToSet - Guid to set as the primary GUID
Return Value:
NET_API_STATUS - NERR_Success or reason for failure.
--*/
{ NET_API_STATUS NetStatus; NTSTATUS Status; LSA_HANDLE PolicyHandle = NULL; PPOLICY_DNS_DOMAIN_INFO PrimaryDomainInfo = NULL; OBJECT_ATTRIBUTES ObjAttributes;
//
// Open a handle to the LSA.
//
InitializeObjectAttributes( &ObjAttributes, NULL, 0L, NULL, NULL );
Status = LsaOpenPolicy( NULL, &ObjAttributes, POLICY_VIEW_LOCAL_INFORMATION | POLICY_TRUST_ADMIN, &PolicyHandle );
if (! NT_SUCCESS(Status)) { NetStatus = NetpNtStatusToApiStatus(Status); goto Cleanup; }
//
// Get the name of the primary domain from LSA
//
Status = LsaQueryInformationPolicy( PolicyHandle, PolicyDnsDomainInformation, (PVOID *) &PrimaryDomainInfo );
if (! NT_SUCCESS(Status)) { NetStatus = NetpNtStatusToApiStatus(Status); goto Cleanup; }
//
// Set the new GUID of the primary domain into the LSA
//
PrimaryDomainInfo->DomainGuid = *GuidToSet;
Status = LsaSetInformationPolicy( PolicyHandle, PolicyDnsDomainInformation, (PVOID) PrimaryDomainInfo );
if (! NT_SUCCESS(Status)) { NetStatus = NetpNtStatusToApiStatus(Status); goto Cleanup; }
NetStatus = NO_ERROR;
Cleanup: if ( PrimaryDomainInfo != NULL ) { (void) LsaFreeMemory((PVOID) PrimaryDomainInfo); } if ( PolicyHandle != NULL ) { (void) LsaClose(PolicyHandle); }
return NetStatus;
}
/*!--------------------------------------------------------------------------
DsGetDcGlobalPrint - Author: KennT ---------------------------------------------------------------------------*/ void DsGetDcGlobalPrint( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults) { if (pParams->fVerbose || !FHrOK(pResults->DsGetDc.hr)) { PrintNewLine(pParams, 2); PrintTestTitleResult(pParams, IDS_DSGETDC_LONG, IDS_DSGETDC_SHORT, pResults->DsGetDc.fPerformed, pResults->DsGetDc.hr, 0); if (pParams->fReallyVerbose || !FHrOK(pResults->DsGetDc.hr)) PrintMessageList(pParams, &pResults->DsGetDc.lmsgOutput); }
}
/*!--------------------------------------------------------------------------
DsGetDcPerInterfacePrint - Author: KennT ---------------------------------------------------------------------------*/ void DsGetDcPerInterfacePrint( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults, INTERFACE_RESULT *pInterfaceResults) { // no per-interface results
}
/*!--------------------------------------------------------------------------
DsGetDcCleanup - Author: KennT ---------------------------------------------------------------------------*/ void DsGetDcCleanup( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults) { MessageListCleanUp(&pResults->DsGetDc.lmsgOutput); }
|