Source code of Windows XP (NT5)
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.

1664 lines
56 KiB

  1. //++
  2. //
  3. // Copyright (C) Microsoft Corporation, 1987 - 1999
  4. //
  5. // Module Name:
  6. //
  7. // dnstest.c
  8. //
  9. // Abstract:
  10. //
  11. // Queries into network drivers
  12. //
  13. // Author:
  14. //
  15. // Anilth - 4-20-1998
  16. //
  17. // Environment:
  18. //
  19. // User mode only.
  20. // Contains NT-specific code.
  21. //
  22. // Revision History:
  23. //
  24. // ElenaAp - 10-22-1998
  25. //
  26. //--
  27. #include "precomp.h"
  28. #include "dnscmn.h"
  29. BOOL DnsServerUp(LPSTR IpAddressString,
  30. NETDIAG_PARAMS *pParams,
  31. NETDIAG_RESULT *pResults,
  32. INTERFACE_RESULT *pIfResults);
  33. BOOL DnsServerHasRecords(LPSTR IpAddressString,
  34. NETDIAG_PARAMS *pParams,
  35. NETDIAG_RESULT *pResults,
  36. INTERFACE_RESULT *pIfResults);
  37. BOOL DnsServerHasDCRecords (NETDIAG_PARAMS *pParams,
  38. NETDIAG_RESULT *pResults,
  39. LPSTR IpAddressString);
  40. BOOL ReadStringToDnsRecord(IN LPSTR lpstrString, OUT PDNS_RECORD pDNSRecord);
  41. VOID PrintDNSError(IN NETDIAG_PARAMS *pParams,
  42. IN NETDIAG_RESULT *pResults,
  43. IN DWORD status,
  44. IN NdVerbose ndv);
  45. VOID PrintARecord (IN NETDIAG_PARAMS *pParams, IN PDNS_RECORD pDnsRecord );
  46. VOID PrintSRVRecord (IN NETDIAG_PARAMS *pParams, IN PDNS_RECORD pDnsRecord );
  47. VOID PrintCNAMERecord (IN NETDIAG_PARAMS *pParams, IN PDNS_RECORD pDnsRecord );
  48. VOID PrintRecord (IN NETDIAG_PARAMS *pParams,
  49. IN NETDIAG_RESULT *pResults,
  50. IN PDNS_RECORD pDnsRecord,
  51. IN NdVerbose ndv);
  52. HRESULT
  53. DnsTest(NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults)
  54. /*++
  55. Routine Description:
  56. Ensure that DNS is up and running
  57. Arguments:
  58. None.
  59. Return Value:
  60. TRUE: Test suceeded.
  61. FALSE: Test failed
  62. --*/
  63. {
  64. NET_API_STATUS NetStatus;
  65. PIP_ADDR_STRING DnsServer;
  66. ULONG WorkingDnsServerCount = 0;
  67. ULONG ConfiguredDnsServerCount = 0;
  68. BOOL fRecordsRegistered = FALSE;
  69. BOOL fDSRecordsRegistered = FALSE;
  70. BOOL fFixOnce = FALSE;
  71. BOOL fBogusDnsRecord = FALSE;
  72. INTERFACE_RESULT * pVariableInfo;
  73. PIP_ADAPTER_INFO pIpVariableInfo;
  74. IP_ADDR_STRING LocalDnsServerList;
  75. PIP_ADDR_STRING DnsServerList;
  76. BOOL fUseOldDnsServerList = FALSE;
  77. HRESULT hr = hrOK, hrTemp = hrOK;
  78. WCHAR wszBuffer[DNS_MAX_NAME_BUFFER_LENGTH];
  79. DWORD dwSize = DNS_MAX_NAME_BUFFER_LENGTH;
  80. int i, ids;
  81. PDNS_NETINFO pNetworkInfo = NULL;
  82. DNS_STATUS dwStatus = NO_ERROR;
  83. LPTSTR pError = NULL;
  84. BOOL bDnscacheRunning = TRUE;
  85. BOOL bGetComputerName = TRUE;
  86. PIP_ARRAY pDnsServers = NULL;
  87. DWORD idx, dwError;
  88. InitializeListHead(&pResults->Dns.lmsgOutput);
  89. for ( i=0; i<pResults->cNumInterfaces; i++)
  90. InitializeListHead( &pResults->pArrayInterface[i].Dns.lmsgOutput );
  91. PrintStatusMessage(pParams, 4, IDS_DNS_STATUS_MSG);
  92. //
  93. // Ensure the DNS cache resolver is running.
  94. //
  95. NetStatus = IsServiceStarted( _T("DnsCache") );
  96. if ( NetStatus != NO_ERROR )
  97. {
  98. PrintStatusMessage(pParams, 0, IDS_DNS_RESOLVER_CACHE_IS_OFF, NetStatusToString(NetStatus));
  99. pResults->Dns.fOutput = TRUE;
  100. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet,
  101. IDS_DNS_RESOLVER_CACHE_IS_OFF, NetStatusToString(NetStatus));
  102. bDnscacheRunning = FALSE;
  103. }
  104. //
  105. // For validation we must use the UNICODE DNS name, not the ANSI name
  106. //
  107. if (!GetComputerNameExW( ComputerNameDnsFullyQualified, wszBuffer, &dwSize ))
  108. {
  109. dwError = GetLastError();
  110. // "[WARNING] GetComputerNameExW() failed with error %d\n"
  111. PrintStatusMessage(pParams, 0, IDS_DNS_12948, dwError);
  112. pResults->Dns.fOutput = TRUE;
  113. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  114. IDS_DNS_12948, dwError);
  115. }
  116. else
  117. {
  118. NetStatus = DnsValidateDnsName_W( wszBuffer );
  119. if ( NetStatus != NO_ERROR )
  120. {
  121. if ( NetStatus == DNS_ERROR_NON_RFC_NAME )
  122. {
  123. // "[WARNING] DnsHostName '%S' valid only on NT 5.0 DNS servers. [%s]\n"
  124. ids = IDS_DNS_NAME_VALID_NT5_ONLY;
  125. }
  126. else
  127. {
  128. // "[FATAL] DnsHostName '%S' is not valid. [%s]\n",
  129. ids = IDS_DNS_NAME_INVALID;
  130. hr = S_FALSE;
  131. }
  132. PrintStatusMessage(pParams, 0, ids, wszBuffer, NetStatusToString(NetStatus));
  133. pResults->Dns.fOutput = TRUE;
  134. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  135. ids, wszBuffer, NetStatusToString(NetStatus));
  136. }
  137. }
  138. //
  139. // Get the DNS Network Information
  140. // Force rediscovery
  141. //
  142. pNetworkInfo = DnsQueryConfigAlloc(
  143. DnsConfigNetInfo,
  144. NULL );
  145. if (!pNetworkInfo)
  146. {
  147. dwStatus = GetLastError(); pError = NetStatusToString(dwStatus);
  148. // [FATAL] Cannot get the DNS Adapter Information from registry, error 0x%x %s\n
  149. PrintStatusMessage(pParams, 0, IDS_DNS_12877, dwStatus, pError);
  150. pResults->Dns.fOutput = TRUE;
  151. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet,
  152. IDS_DNS_12877, dwStatus, pError);
  153. hr = S_FALSE;
  154. goto Error;
  155. }
  156. //
  157. // See if we have at least one DNS server
  158. // If there are no DNS servers at all,
  159. // That's fatal.
  160. //
  161. dwStatus = GetAllDnsServersFromRegistry(pNetworkInfo, &pDnsServers);
  162. if (dwStatus)
  163. {
  164. if (dwStatus == DNS_ERROR_INVALID_DATA)
  165. {
  166. // IDS_DNS_12872 "[FATAL] No DNS servers are configured.\n"
  167. PrintStatusMessage(pParams, 8, IDS_DNS_12872);
  168. pResults->Dns.fOutput = TRUE;
  169. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  170. IDS_DNS_12872);
  171. }
  172. else
  173. {
  174. // IDS_DNS_12885 "[FATAL] Cannot get the DNS server list, error %d %s\n"
  175. PrintStatusMessage(pParams, 8, IDS_DNS_12885, dwStatus, NetStatusToString(dwStatus));
  176. pResults->Dns.fOutput = TRUE;
  177. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  178. IDS_DNS_12885, dwStatus, NetStatusToString(dwStatus));
  179. }
  180. hr = S_FALSE;
  181. goto Error;
  182. }
  183. // check the DNS registration
  184. hrTemp = CheckDnsRegistration(pNetworkInfo, pParams, pResults);
  185. hr = ((hr == S_FALSE) ? hr : hrTemp);
  186. //
  187. //if this is a DC, check if all the dns entries in
  188. //netlogon.dns are registered on DNS servers
  189. //
  190. if ( (pResults->Global.pPrimaryDomainInfo->MachineRole == DsRole_RoleBackupDomainController) ||
  191. (pResults->Global.pPrimaryDomainInfo->MachineRole == DsRole_RolePrimaryDomainController) )
  192. {
  193. //
  194. // go through list of DNS servers and check DC registration
  195. //
  196. for (idx = 0; idx < pDnsServers->AddrCount; idx++)
  197. {
  198. //
  199. //(nsun) we need just fix the DC records on one DNS server and that DNS server will replicate the
  200. // the fix on other DNS servers
  201. //
  202. if ( !fFixOnce )
  203. {
  204. if (DnsServerHasDCRecords( pParams,
  205. pResults,
  206. IP_STRING(pDnsServers->AddrArray[idx])))
  207. fDSRecordsRegistered = TRUE;
  208. }
  209. if ( pParams->fFixProblems )
  210. fFixOnce = TRUE;
  211. }
  212. if( !fDSRecordsRegistered )
  213. {
  214. PrintStatusMessage(pParams, 8, IDS_DNS_DC_FAILURE);
  215. //IDS_DNS_DC_FAILURE "[FATAL] No DNS servers have our DNS records for this DC registered.\n"
  216. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  217. IDS_DNS_DC_FAILURE);
  218. hr = S_FALSE;
  219. }
  220. }
  221. /*
  222. //
  223. // If we're running a build that's older than ipconfig can handle,
  224. // build our own list of DNS servers directly from the registry.
  225. //
  226. if ( _ttoi(pResults->Global.pszCurrentBuildNumber) < NTBUILD_DNSSERVERLIST)
  227. {
  228. HKEY TcpipParametersKey;
  229. HKEY TransientKey;
  230. LPSTR Name;
  231. BOOLEAN ok;
  232. BOOL ReadRegistryIpAddrString(HKEY, LPSTR, PIP_ADDR_STRING);
  233. RtlZeroMemory( &LocalDnsServerList, sizeof(LocalDnsServerList));
  234. Name = "SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters";
  235. NetStatus = RegOpenKey( HKEY_LOCAL_MACHINE, Name, &TcpipParametersKey );
  236. if ( NetStatus != NO_ERROR )
  237. {
  238. PrintDebugSz(pParams, 0, _T(" [FATAL] Cannot open key '%s'. [%s]\n"),
  239. Name, NetStatusToString(NetStatus) );
  240. hr = S_FALSE;
  241. goto Error;
  242. }
  243. //
  244. // NameServer: 1st try Transient key then NameServer (override) in
  245. // Parameters key, and finally DhcpNameServer in parameters key
  246. //
  247. if (RegOpenKey(TcpipParametersKey, "Transient", &TransientKey) == ERROR_SUCCESS) {
  248. ok = ReadRegistryIpAddrString(TransientKey,
  249. "NameServer",
  250. &LocalDnsServerList
  251. );
  252. RegCloseKey(TransientKey);
  253. } else {
  254. ok = FALSE;
  255. }
  256. if (!ok) {
  257. ok = ReadRegistryIpAddrString(TcpipParametersKey,
  258. "NameServer",
  259. &LocalDnsServerList
  260. );
  261. }
  262. if (!ok) {
  263. ok = ReadRegistryIpAddrString(TcpipParametersKey,
  264. "DhcpNameServer",
  265. &LocalDnsServerList
  266. );
  267. }
  268. RegCloseKey(TcpipParametersKey);
  269. fUseOldDnsServerList = TRUE;
  270. }
  271. //
  272. // Test the DNS servers for each adapter
  273. //
  274. for ( i=0; i<pResults->cNumInterfaces; i++)
  275. {
  276. pVariableInfo = pResults->pArrayInterface + i;
  277. pIpVariableInfo = pVariableInfo->IpConfig.pAdapterInfo;
  278. if (!pVariableInfo->IpConfig.fActive)
  279. continue;
  280. //
  281. // Use the old Dns server list or the per adapter one depending on
  282. // what build we're running.
  283. //
  284. if ( fUseOldDnsServerList )
  285. {
  286. DnsServerList = &LocalDnsServerList;
  287. }
  288. else
  289. {
  290. DnsServerList = &pVariableInfo->IpConfig.DnsServerList;
  291. PrintStatusMessage(pParams, 8, IDS_DNS_CHECKING_DNS_SERVERS,
  292. pVariableInfo->pszFriendlyName);
  293. AddMessageToListSz(&pVariableInfo->Dns.lmsgOutput, Nd_ReallyVerbose,
  294. _T(" "));
  295. AddMessageToList(&pVariableInfo->Dns.lmsgOutput, Nd_ReallyVerbose,
  296. IDS_DNS_CHECKING_DNS_SERVERS,
  297. pVariableInfo->pszFriendlyName);
  298. }
  299. //
  300. // Make sure all of the DNS servers are up.
  301. //
  302. for ( DnsServer = DnsServerList;
  303. DnsServer;
  304. DnsServer = DnsServer->Next)
  305. {
  306. if ( DnsServer->IpAddress.String[0] == '\0' )
  307. {
  308. fBogusDnsRecord = TRUE;
  309. continue;
  310. }
  311. ConfiguredDnsServerCount++;
  312. if ( DnsServerUp( DnsServer->IpAddress.String,
  313. pParams,
  314. pResults,
  315. pVariableInfo) )
  316. {
  317. if ( pParams->fReallyVerbose)
  318. {
  319. // IDS_DNS_SERVER_IS_UP "DNS server at %s is up.\n"
  320. AddMessageToList(&pVariableInfo->Dns.lmsgOutput,
  321. Nd_ReallyVerbose,
  322. IDS_DNS_SERVER_IS_UP,
  323. DnsServer->IpAddress.String );
  324. }
  325. WorkingDnsServerCount ++;
  326. //
  327. // Since the server is up,
  328. // check to see that it has all of the right records registered.
  329. //
  330. if ( DnsServerHasRecords( DnsServer->IpAddress.String, pParams, pResults, pVariableInfo) ) {
  331. fRecordsRegistered = TRUE;
  332. }
  333. if ((hr == hrOK))
  334. {
  335. // check DC dns entry here
  336. //
  337. //if this is a DC, we check if all the dns entries in
  338. //netlogon.dns are registered on DNS server
  339. //
  340. if ( pResults->Global.pPrimaryDomainInfo->MachineRole ==
  341. DsRole_RoleBackupDomainController ||
  342. pResults->Global.pPrimaryDomainInfo->MachineRole ==
  343. DsRole_RolePrimaryDomainController )
  344. {
  345. //(nsun) we need just fix the DC records on one DNS server and that DNS server will replicate the
  346. // the fix on other DNS servers
  347. if ( !fFixOnce )
  348. {
  349. if (DnsServerHasDCRecords( pParams,
  350. pResults,
  351. DnsServer->IpAddress.String))
  352. fDSRecordsRegistered = TRUE;
  353. }
  354. if ( pParams->fFixProblems )
  355. fFixOnce = TRUE;
  356. }
  357. // if it is not a DC, we don't check it later.
  358. else
  359. fDSRecordsRegistered = TRUE;
  360. }
  361. }
  362. }
  363. //
  364. // There isn't one old list per adapter
  365. //
  366. if ( fUseOldDnsServerList ) {
  367. break;
  368. }
  369. }
  370. //
  371. // If there are no DNS servers at all,
  372. // That's fatal.
  373. //
  374. if ( ConfiguredDnsServerCount == 0 )
  375. {
  376. if ( !fBogusDnsRecord )
  377. {
  378. // IDS_DNS_12872 "[FATAL] No DNS servers are configured.\n"
  379. PrintStatusMessage(pParams, 8, IDS_DNS_12872);
  380. pResults->Dns.fOutput = TRUE;
  381. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  382. IDS_DNS_12872);
  383. hr = S_FALSE;
  384. }
  385. //
  386. // If there are no working DNS servers,
  387. // That's fatal.
  388. //
  389. }
  390. else if ( WorkingDnsServerCount == 0 )
  391. {
  392. // IDS_DNS_12873 "[FATAL] No DNS servers are working.\n"
  393. PrintStatusMessage(pParams, 8, IDS_DNS_12873);
  394. pResults->Dns.fOutput = TRUE;
  395. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  396. IDS_DNS_12873);
  397. hr = S_FALSE;
  398. }
  399. else
  400. {
  401. if ( !fRecordsRegistered )
  402. {
  403. //
  404. // Warn if no DNS servers have our addresses registered.
  405. // (But still not fatal).
  406. //
  407. // IDS_DNS_12874 "[WARNING] No DNS servers have our records registered.\n"
  408. PrintStatusMessage(pParams, 8, IDS_DNS_12874);
  409. pResults->Dns.fOutput = TRUE;
  410. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  411. IDS_DNS_12874);
  412. }
  413. */
  414. DnsFreeConfigStructure(
  415. pNetworkInfo,
  416. DnsConfigNetInfo );
  417. if (pDnsServers) LocalFree (pDnsServers);
  418. pResults->Dns.hr = hr;
  419. return hr;
  420. Error:
  421. if (pDnsServers) LocalFree (pDnsServers);
  422. pResults->Dns.hr = hr;
  423. return hr;
  424. }
  425. BOOL
  426. DnsServerUp(
  427. LPSTR IpAddressString,
  428. NETDIAG_PARAMS *pParams,
  429. NETDIAG_RESULT *pResults,
  430. INTERFACE_RESULT *pIfResults
  431. )
  432. /*++
  433. Routine Description:
  434. Determine if the DNS server at the specified address is up and running.
  435. Arguments:
  436. IpAddressString - Ip Address of a DNS server
  437. Return Value:
  438. TRUE: Dns server is up.
  439. FALSE: Dns server is not up
  440. --*/
  441. {
  442. NET_API_STATUS NetStatus;
  443. BOOL RetVal = TRUE;
  444. CHAR SoaNameBuffer[DNS_MAX_NAME_LENGTH+1];
  445. PCHAR SoaName;
  446. PCHAR OldSoaName;
  447. PDNS_RECORD DnsRecord = NULL;
  448. SOCKADDR_IN SockAddr;
  449. ULONG SockAddrSize;
  450. IP_ARRAY DnsServer;
  451. //
  452. // Ping the DNS server.
  453. //
  454. if ( !IsIcmpResponseA( IpAddressString) )
  455. {
  456. PrintStatusMessage(pParams, 12, IDS_DNS_CANNOT_PING, IpAddressString);
  457. pIfResults->Dns.fOutput = TRUE;
  458. AddIMessageToList(&pIfResults->Dns.lmsgOutput, Nd_Quiet, 16,
  459. IDS_DNS_CANNOT_PING, IpAddressString);
  460. RetVal = FALSE;
  461. goto Cleanup;
  462. }
  463. //
  464. // Compute the name of an SOA record.
  465. //
  466. if (pResults->Global.pszDnsDomainName == NULL)
  467. {
  468. //IDS_DNS_12821 " [FATAL] Cannot test DNS server at %s since no DnsDomainName\n."
  469. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12821, IpAddressString );
  470. RetVal = FALSE;
  471. goto Cleanup;
  472. }
  473. strcpy( SoaNameBuffer, pResults->Global.pszDnsDomainName );
  474. SoaName = SoaNameBuffer;
  475. //
  476. // Tell DNS which Dns Server to use
  477. //
  478. DnsServer.AddrCount = 1;
  479. SockAddrSize = sizeof(SockAddr);
  480. NetStatus = WSAStringToAddress( IpAddressString,
  481. AF_INET,
  482. NULL,
  483. (LPSOCKADDR) &SockAddr,
  484. &SockAddrSize );
  485. if ( NetStatus != NO_ERROR ) {
  486. NetStatus = WSAGetLastError();
  487. //IDS_DNS_12822 " [FATAL] Cannot convert DNS server address %s to SockAddr. [%s]\n"
  488. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12822, IpAddressString, NetStatusToString(NetStatus));
  489. RetVal = FALSE;
  490. goto Cleanup;
  491. }
  492. DnsServer.AddrArray[0] = SockAddr.sin_addr.S_un.S_addr;
  493. //
  494. // Loop until the real SOA record is found
  495. //
  496. for (;;) {
  497. //
  498. // Query this DNS server for the SOA record.
  499. //
  500. NetStatus = DnsQuery( SoaName,
  501. DNS_TYPE_SOA,
  502. DNS_QUERY_BYPASS_CACHE |
  503. DNS_QUERY_NO_RECURSION,
  504. &DnsServer,
  505. &DnsRecord,
  506. NULL );
  507. if ( NetStatus == NO_ERROR ) {
  508. if ( DnsRecord != NULL ) {
  509. DnsRecordListFree ( DnsRecord, TRUE );
  510. }
  511. DnsRecord = NULL;
  512. break;
  513. }
  514. switch ( NetStatus ) {
  515. case ERROR_TIMEOUT: // DNS server isn't available
  516. case DNS_ERROR_RCODE_SERVER_FAILURE: // Server failed
  517. // IDS_DNS_12823 " [WARNING] DNS server at %s is down for SOA record '%s'. [%s]\n"
  518. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12823, IpAddressString, SoaName, NetStatusToString(NetStatus) );
  519. //IDS_DNS_12825 "\n"
  520. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12825);
  521. RetVal = FALSE;
  522. goto Cleanup;
  523. case DNS_ERROR_NO_TCPIP: // TCP/IP not configured
  524. // IDS_DNS_12826 " [FATAL] DNS (%s) thinks IP is not configured for SOA record '%s'. [%s]\n"
  525. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12826, IpAddressString, SoaName, NetStatusToString(NetStatus) );
  526. RetVal = FALSE;
  527. goto Cleanup;
  528. case DNS_ERROR_NO_DNS_SERVERS: // DNS not configured
  529. // IDS_DNS_12827 " [FATAL] DNS (%s) thinks DNS is not configured for SOA record '%s'. [%s]\n"
  530. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12827, IpAddressString, SoaName, NetStatusToString(NetStatus) );
  531. RetVal = FALSE;
  532. goto Cleanup;
  533. case DNS_ERROR_RCODE_NAME_ERROR: // no RR's by this name
  534. case DNS_INFO_NO_RECORDS: // RR's by this name but not of the requested type:
  535. break;
  536. default:
  537. // IDS_DNS_12828 " [FATAL] Cannot query DNS server at %s for SOA record '%s'. [%s]\n"
  538. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12828, IpAddressString, SoaName, NetStatusToString(NetStatus) );
  539. RetVal = FALSE;
  540. goto Cleanup;
  541. }
  542. //
  543. // Remove the next label from the potential SOA name and use it.
  544. //
  545. SoaName = strchr( SoaName, '.' );
  546. if ( SoaName == NULL )
  547. {
  548. // IDS_DNS_12829 " [FATAL] DNS server at %s could not find an SOA record for '%s'.\n"
  549. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12829, IpAddressString, pResults->Global.pszDnsDomainName );
  550. RetVal = FALSE;
  551. goto Cleanup;
  552. }
  553. SoaName ++;
  554. }
  555. Cleanup:
  556. if ( DnsRecord != NULL ) {
  557. DnsRecordListFree ( DnsRecord, TRUE );
  558. }
  559. return RetVal;
  560. }
  561. BOOL
  562. DnsServerHasRecords(LPSTR IpAddressString,
  563. NETDIAG_PARAMS *pParams,
  564. NETDIAG_RESULT *pResults,
  565. INTERFACE_RESULT *pIfResults
  566. )
  567. /*++
  568. Routine Description:
  569. Determine if the DNS server at the specified address has all of records
  570. registered that that machine is supposed to have registered.
  571. Arguments:
  572. IpAddressString - Ip Address of a DNS server
  573. Return Value:
  574. TRUE: Dns server is up.
  575. FALSE: Dns server is not up
  576. --*/
  577. {
  578. NET_API_STATUS NetStatus;
  579. BOOL RetVal = TRUE;
  580. CHAR LocalIpAddressString[NL_IP_ADDRESS_LENGTH+1];
  581. PDNS_RECORD DnsRecord = NULL;
  582. PDNS_RECORD CurrentDnsRecord;
  583. SOCKADDR_IN SockAddr;
  584. ULONG SockAddrSize;
  585. PLIST_ENTRY ListEntry;
  586. PNETBT_TRANSPORT NetbtTransport;
  587. IP_ARRAY DnsServer;
  588. //
  589. // Avoid this test if this build is incompatible with the current
  590. // Dynamic DNS servers.
  591. //
  592. if ( _ttoi(pResults->Global.pszCurrentBuildNumber) < NTBUILD_DYNAMIC_DNS)
  593. {
  594. // IDS_DNS_CANNO_TEST_DNS "Cannot test Dynamic DNS to %s since this machine is running build %ld. [Test skipped.]\n",
  595. AddMessageToList(&pIfResults->Dns.lmsgOutput,
  596. Nd_ReallyVerbose,
  597. IDS_DNS_CANNOT_TEST_DNS,
  598. IpAddressString, pResults->Global.pszCurrentBuildNumber );
  599. return TRUE;
  600. }
  601. //
  602. // Tell DNS which Dns Server to use
  603. //
  604. DnsServer.AddrCount = 1;
  605. SockAddrSize = sizeof(SockAddr);
  606. NetStatus = WSAStringToAddress( IpAddressString,
  607. AF_INET,
  608. NULL,
  609. (LPSOCKADDR) &SockAddr,
  610. &SockAddrSize );
  611. if ( NetStatus != NO_ERROR )
  612. {
  613. NetStatus = WSAGetLastError();
  614. PrintDebugSz(pParams, 0, _T(" [FATAL] Cannot convert DNS server address %s to SockAddr. [%s]\n"),
  615. IpAddressString, NetStatusToString(NetStatus));
  616. AddMessageToList(&pIfResults->Dns.lmsgOutput,
  617. Nd_ReallyVerbose,
  618. IDS_DNS_CANNOT_CONVERT_DNS_ADDRESS,
  619. IpAddressString, NetStatusToString(NetStatus));
  620. RetVal = FALSE;
  621. goto Cleanup;
  622. }
  623. DnsServer.AddrArray[0] = SockAddr.sin_addr.S_un.S_addr;
  624. //
  625. // Query this DNS server for A record for this hostname
  626. //
  627. NetStatus = DnsQuery( pResults->Global.szDnsHostName,
  628. DNS_TYPE_A,
  629. DNS_QUERY_BYPASS_CACHE,
  630. &DnsServer,
  631. &DnsRecord,
  632. NULL );
  633. switch ( NetStatus )
  634. {
  635. case NO_ERROR:
  636. break;
  637. case ERROR_TIMEOUT: // DNS server isn't available
  638. case DNS_ERROR_RCODE_SERVER_FAILURE: // Server failed
  639. // IDS_DNS_SERVER_IS_DOWN " [WARNING] DNS server at %s is down. [%s]\n"
  640. PrintStatusMessage(pParams, 12, IDS_DNS_SERVER_IS_DOWN, IpAddressString, NetStatusToString(NetStatus));
  641. AddIMessageToList(&pIfResults->Dns.lmsgOutput,
  642. Nd_ReallyVerbose,
  643. 16,
  644. IDS_DNS_SERVER_IS_DOWN,
  645. IpAddressString, NetStatusToString(NetStatus));
  646. RetVal = FALSE;
  647. goto Cleanup;
  648. case DNS_ERROR_NO_TCPIP: // TCP/IP not configured
  649. //IDS_DNS_THINKS_IP_IS_UNCONFIGURED " [FATAL] DNS (%s) thinks IP is not configured. [%s]\n"
  650. AddMessageToList(&pIfResults->Dns.lmsgOutput,
  651. Nd_ReallyVerbose,
  652. IDS_DNS_THINKS_IP_IS_UNCONFIGURED,
  653. IpAddressString, NetStatusToString(NetStatus));
  654. RetVal = FALSE;
  655. goto Cleanup;
  656. case DNS_ERROR_NO_DNS_SERVERS: // DNS not configured
  657. // IDS_DNS_IS_UNCONFIGURED " [FATAL] DNS (%s) thinks DNS is not configured. [%s]\n"
  658. AddMessageToList(&pIfResults->Dns.lmsgOutput,
  659. Nd_ReallyVerbose,
  660. IDS_DNS_IS_UNCONFIGURED,
  661. IpAddressString, NetStatusToString(NetStatus));
  662. RetVal = FALSE;
  663. goto Cleanup;
  664. case DNS_ERROR_RCODE_NAME_ERROR: // no RR's by this name
  665. case DNS_INFO_NO_RECORDS: // RR's by this name but not of the requested type:
  666. // IDS_DNS_HAS_NO_RECORD " [WARNING] DNS server at %s has no A record for '%s'. [%s]\n"
  667. AddMessageToList(&pIfResults->Dns.lmsgOutput,
  668. Nd_ReallyVerbose,
  669. IDS_DNS_HAS_NO_RECORD,
  670. IpAddressString,
  671. pResults->Global.szDnsHostName,
  672. NetStatusToString(NetStatus) );
  673. RetVal = FALSE;
  674. goto Cleanup;
  675. default:
  676. // IDS_DNS_CANNOT_QUERY " [FATAL] Cannot query DNS server at %s. [%s]\n"
  677. AddMessageToList(&pIfResults->Dns.lmsgOutput,
  678. Nd_ReallyVerbose,
  679. IDS_DNS_CANNOT_QUERY,
  680. IpAddressString, pResults->Global.szDnsHostName,
  681. NetStatusToString(NetStatus) );
  682. RetVal = FALSE;
  683. goto Cleanup;
  684. }
  685. //
  686. // We have an A record for ourselves.
  687. //
  688. #ifdef notdef
  689. //IDS_DNS_12830 " DNS server at %s has an A record for '%s'.\n"
  690. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12830, IpAddressString, pResults->Global.szDnsHostName );
  691. if ( pParams->fDebugVerbose ) {
  692. PrintMessage(pParams, IDS_DNS_12830, IpAddressString, pResults->Global.szDnsHostName );
  693. //IDS_DNS_12831 " A"
  694. DnsPrint_RecordSet( &PrintMessage(pParams, IDS_DNS_12831, DnsRecord );
  695. }
  696. #endif // notdef
  697. //
  698. // Match the IP address on the A records with the IP address of this machine
  699. //
  700. // Mark each transport that its IP address hasn't yet been found.
  701. //
  702. for ( ListEntry = pResults->NetBt.Transports.Flink ;
  703. ListEntry != &pResults->NetBt.Transports ;
  704. ListEntry = ListEntry->Flink ) {
  705. NetbtTransport = CONTAINING_RECORD( ListEntry, NETBT_TRANSPORT, Next );
  706. NetbtTransport->Flags &= ~IP_ADDRESS_IN_DNS;
  707. }
  708. //
  709. // Loop through the A records
  710. //
  711. for ( CurrentDnsRecord = DnsRecord;
  712. CurrentDnsRecord;
  713. CurrentDnsRecord = CurrentDnsRecord->pNext )
  714. {
  715. //
  716. // Ignore everything but A records.
  717. //
  718. if ( CurrentDnsRecord->wType == DNS_TYPE_A )
  719. {
  720. BOOLEAN FoundIt = FALSE;
  721. //
  722. // Loop through the list of netbt transports finding one with this IP address.
  723. //
  724. for ( ListEntry = pResults->NetBt.Transports.Flink ;
  725. ListEntry != &pResults->NetBt.Transports ;
  726. ListEntry = ListEntry->Flink )
  727. {
  728. NetbtTransport = CONTAINING_RECORD( ListEntry, NETBT_TRANSPORT, Next );
  729. if ( NetbtTransport->IpAddress == CurrentDnsRecord->Data.A.IpAddress )
  730. {
  731. FoundIt = TRUE;
  732. NetbtTransport->Flags |= IP_ADDRESS_IN_DNS;
  733. }
  734. }
  735. if ( !FoundIt )
  736. {
  737. NetpIpAddressToStr( CurrentDnsRecord->Data.A.IpAddress, LocalIpAddressString );
  738. // IDS_DNS_HAS_A_RECORD " [WARNING] DNS server at %s has an A record for '%s' with wrong IP address: %s", IpAddressString, pResults->Global.szDnsHostName, LocalIpAddressString );
  739. AddMessageToList(&pIfResults->Dns.lmsgOutput,
  740. Nd_ReallyVerbose,
  741. IDS_DNS_HAS_A_RECORD,
  742. IpAddressString,
  743. pResults->Global.szDnsHostName,
  744. LocalIpAddressString );
  745. RetVal = FALSE;
  746. }
  747. }
  748. }
  749. //
  750. // If all of the addresses of this machine aren't registered,
  751. // complain.
  752. //
  753. for ( ListEntry = pResults->NetBt.Transports.Flink ;
  754. ListEntry != &pResults->NetBt.Transports ;
  755. ListEntry = ListEntry->Flink )
  756. {
  757. NetbtTransport = CONTAINING_RECORD( ListEntry, NETBT_TRANSPORT, Next );
  758. if ( (NetbtTransport->Flags & IP_ADDRESS_IN_DNS) == 0 )
  759. {
  760. NetpIpAddressToStr( NetbtTransport->IpAddress, LocalIpAddressString );
  761. // IDS_DNS_HAS_NO_A_RECORD " [WARNING] DNS server at %s does not have an A record for '%s' with IP address: %s (%ws)", IpAddressString, pResults->Global.szDnsHostName, LocalIpAddressString, NetbtTransport->pswzTransportName );
  762. AddMessageToList(&pIfResults->Dns.lmsgOutput,
  763. Nd_ReallyVerbose,
  764. IDS_DNS_HAS_NO_A_RECORD,
  765. IpAddressString,
  766. pResults->Global.szDnsHostName,
  767. LocalIpAddressString,
  768. NetbtTransport->pswzTransportName );
  769. RetVal = FALSE;
  770. }
  771. }
  772. Cleanup:
  773. if ( DnsRecord != NULL ) {
  774. DnsRecordListFree ( DnsRecord, TRUE );
  775. }
  776. return RetVal;
  777. }
  778. BOOL
  779. DnsServerHasDCRecords ( NETDIAG_PARAMS *pParams,
  780. NETDIAG_RESULT *pResults,
  781. LPSTR IpAddressString)
  782. /*++
  783. Routine Description:
  784. On a DC machine, Open file (%systemroot%\system32\config\netlogon.dns) and read the dns entry from it.
  785. Query the specified dns server for the entry and confirm it is correct.
  786. Reupdate these entry if /fix option is on.
  787. Arguments: IpAddressString - DNS server IP address
  788. Return Value:
  789. TRUE: Query succeed.
  790. FALSE: failed.
  791. --*/
  792. {
  793. char pchDnsDataFileName[MAX_PATH] = "\\config\\netlogon.dns";
  794. char pchDnsDataFileExpandName[MAX_PATH];
  795. FILE *fDnsFile;
  796. PIP_ARRAY pIpArray = NULL;
  797. CHAR achTempLine[ NL_MAX_DNS_LENGTH*3+1 ];
  798. INT iMaxLineLength;
  799. DWORD status, dwOptions = DNS_QUERY_BYPASS_CACHE;
  800. PDNS_RECORD pDNSRecord = NULL;
  801. PDNS_RECORD pDNSTempRecord = NULL;
  802. PDNS_RECORD pDiff1=NULL, pDiff2=NULL;
  803. PDNS_RECORD pNotUsedSet = NULL;
  804. BOOL bReRegister, bReadData = FALSE, bFixFail = FALSE;
  805. BOOL fRetVal = TRUE;
  806. enum _Results // Declare enum type
  807. {
  808. enumSuccess,
  809. enumRegistered,
  810. enumProblem,
  811. enumTimeout
  812. } Results;
  813. Results = enumSuccess;
  814. pIpArray = (PIP_ARRAY) LocalAlloc( LPTR,
  815. ( sizeof(IP_ADDRESS) + sizeof(DWORD) ));
  816. // "Check the DNS registration for DCs entries on DNS server %s\n"
  817. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12944, IpAddressString);
  818. if ( ! pIpArray ) {
  819. DebugMessage(" [FATAL] No enough memory to create IpArray.");
  820. return ( FALSE );
  821. }
  822. pIpArray->AddrCount = 1;
  823. pIpArray->AddrArray[0] = inet_addr( IpAddressString );
  824. if ( pIpArray->AddrArray[0] == INADDR_NONE) {
  825. //IDS_DNS_IPADDR_ERR " [FATAL] Cannot convert DNS server address %s, failed in inet_addr().\n"
  826. PrintStatusMessage(pParams, 0, IDS_DNS_IPADDR_ERR, IpAddressString);
  827. pResults->Dns.fOutput = TRUE;
  828. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_IPADDR_ERR, IpAddressString);
  829. return( FALSE );
  830. }
  831. //
  832. //open file
  833. //
  834. if ( ! GetSystemDirectory ( pchDnsDataFileExpandName, MAX_PATH)) {
  835. // IDS_DNS_12832 " [FATAL] Could not GetSystemDir %s for reading."
  836. PrintStatusMessage(pParams, 0, IDS_DNS_12832, pchDnsDataFileExpandName);
  837. pResults->Dns.fOutput = TRUE;
  838. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet,
  839. IDS_DNS_12832,
  840. pchDnsDataFileExpandName);
  841. return FALSE;
  842. }
  843. strcat( pchDnsDataFileExpandName, pchDnsDataFileName);
  844. if (( fDnsFile = fopen (pchDnsDataFileExpandName, "rt")) == NULL) {
  845. //IDS_DNS_12833 " [FATAL] Could not open file %s for reading."
  846. PrintStatusMessage(pParams, 0, IDS_DNS_12833, pchDnsDataFileExpandName);
  847. pResults->Dns.fOutput = TRUE;
  848. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet,
  849. IDS_DNS_12833,
  850. pchDnsDataFileExpandName);
  851. return FALSE ;
  852. }
  853. //
  854. //allocate memory for pDNSRecord
  855. //
  856. pDNSRecord = (PDNS_RECORD) Malloc( sizeof( DNS_RECORD ) );
  857. if ( !pDNSRecord )
  858. {
  859. // IDS_DNS_12834 "Out of Memory: LocalAlloc(sizeof(DNS_RECORD)) call failed.\n"
  860. PrintStatusMessage(pParams, 0, IDS_DNS_12834);
  861. pResults->Dns.fOutput = TRUE;
  862. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12834 );
  863. return( FALSE );
  864. }
  865. ZeroMemory( pDNSRecord, sizeof( DNS_RECORD ) );
  866. //read each line
  867. //do query one by one
  868. //print out msg
  869. //do reupdate
  870. //check the result
  871. //
  872. // Parse the file line by line
  873. //
  874. iMaxLineLength = NL_MAX_DNS_LENGTH*3+1 ;
  875. while( fgets( achTempLine, iMaxLineLength, fDnsFile ) != NULL)
  876. {
  877. //
  878. // Read the data into pDNSRecord
  879. //
  880. if (ReadStringToDnsRecord(achTempLine, pDNSRecord))
  881. {
  882. bReadData = TRUE ;
  883. if ( pParams->fDebugVerbose )
  884. {
  885. //IDS_DNS_12835 "\n********** * ********** * ********** * ********** * ********** *\n"
  886. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_DebugVerbose, IDS_DNS_12835);
  887. //IDS_DNS_12836 "* CHECK NAME %s on DNS server %s\n"
  888. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_DebugVerbose, IDS_DNS_12836,
  889. UTF8ToAnsi(pDNSRecord->pName), IpAddressString);
  890. //IDS_DNS_12837 "********** * ********** * ********** * ********** * ********** *\n\n"
  891. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_DebugVerbose, IDS_DNS_12837);
  892. }
  893. bReRegister = FALSE;
  894. //
  895. // make the query
  896. //
  897. status = DnsQuery_UTF8(
  898. pDNSRecord->pName,
  899. pDNSRecord->wType,
  900. dwOptions,
  901. pIpArray,
  902. &pDNSTempRecord,
  903. NULL );
  904. if ( status )
  905. {
  906. //IDS_DNS_12838 "Query for DC DNS entry %s on DNS server %s failed.\n"
  907. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12838,
  908. UTF8ToAnsi(pDNSRecord->pName), IpAddressString);
  909. PrintDNSError( pParams, pResults, status, Nd_ReallyVerbose );
  910. bReRegister = TRUE;
  911. Results = enumProblem;
  912. //
  913. // if result was TIMEOUT do not continue querying this server
  914. //
  915. if ( status == ERROR_TIMEOUT )
  916. {
  917. Results = enumTimeout;
  918. break;
  919. }
  920. }
  921. else
  922. {
  923. //
  924. // Sometimes when DnsQuery is called, the returned record set
  925. // contains additional records of different types than what
  926. // was queried for. Need to strip off the additional records
  927. // from the query results.
  928. //
  929. pNotUsedSet = DnsRecordSetDetach( pDNSTempRecord );
  930. if ( pNotUsedSet ) {
  931. DnsRecordListFree( pNotUsedSet, TRUE );
  932. pNotUsedSet = NULL;
  933. }
  934. if ( DnsRecordSetCompare(
  935. pDNSRecord,
  936. pDNSTempRecord,
  937. &pDiff1,
  938. &pDiff2 ))
  939. {
  940. //
  941. // The response from dns server is the same as the data in the file
  942. //
  943. //PrintDebugSz(pParams, 0, _T("The Record is correct on dns server %s!\n\n"), IpAddressString);
  944. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12941, IpAddressString);
  945. }
  946. else
  947. {
  948. //
  949. // The RR on dns server is different, we check if it is one of the RR on dns server
  950. //
  951. // PrintDebugSz(pParams, 0, _T("The Record is different on dns server %s.\n"), IpAddressString);
  952. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12942, IpAddressString);
  953. if (pDiff1 == NULL)
  954. {
  955. //"DNS server has more than one entries for this name, usually this means there are multiple DCs for this domain.\nYour DC entry is one of them on DNS server %s, no need to re-register.\n"
  956. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12943, IpAddressString);
  957. if ( Results == enumSuccess )
  958. Results = enumRegistered;
  959. }
  960. else
  961. {
  962. Results = enumProblem;
  963. bReRegister = TRUE;
  964. }
  965. //IDS_DNS_12839 "\n+------------------------------------------------------+\n"
  966. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12839);
  967. //IDS_DNS_12840 "The record on your DC is: \n"
  968. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12840);
  969. PrintRecord(pParams, pResults, pDNSRecord, Nd_ReallyVerbose );
  970. //IDS_DNS_12841 "\nThe record on DNS server %s is:\n"
  971. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12841, IpAddressString);
  972. PrintRecord(pParams, pResults, pDNSTempRecord, Nd_ReallyVerbose );
  973. //IDS_DNS_12842 "+------------------------------------------------------+\n\n"
  974. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12842);
  975. }
  976. }
  977. if ( bReRegister && pParams->fFixProblems)
  978. {
  979. //
  980. // Send to register again
  981. //
  982. // IDS_DNS_12843 " [Fix] Try to re-register the record on DNS server %s...\n"
  983. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12843, IpAddressString);
  984. status = DnsModifyRecordsInSet(
  985. pDNSRecord, // add records
  986. NULL, // no delete records
  987. 0, // no options
  988. NULL, // default security context
  989. pIpArray, // DNS servers
  990. NULL
  991. );
  992. if ( status != ERROR_SUCCESS )
  993. {
  994. // IDS_DNS_12844 " [FATAL] Failed to fix: DC DNS entry %s re-registeration on DNS server %s failed. \n"
  995. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12844, pDNSRecord->pName, IpAddressString);
  996. PrintDNSError( pParams, pResults, status, Nd_Quiet );
  997. bFixFail = TRUE;
  998. }
  999. else
  1000. {
  1001. //IDS_DNS_12845 " [FIX] re-register DC DNS entry %s on DNS server %s succeed.\n"
  1002. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Verbose, IDS_DNS_12845, UTF8ToAnsi(pDNSRecord->pName), IpAddressString );
  1003. }
  1004. }
  1005. //
  1006. // free the memory after process each line
  1007. //
  1008. if ( pDNSTempRecord )
  1009. DnsRecordListFree( pDNSTempRecord, TRUE );
  1010. if ( pDiff1 ){
  1011. DnsRecordListFree( pDiff1, TRUE );
  1012. pDiff1 = NULL;
  1013. }
  1014. if ( pDiff2 ) {
  1015. DnsRecordListFree( pDiff2, TRUE );
  1016. pDiff2 = NULL;
  1017. }
  1018. }
  1019. else {
  1020. bReadData = FALSE ;
  1021. }
  1022. }
  1023. // "\n ** ** Check DC DNS NAME FINAL RESULT ** ** \n"
  1024. if ( pParams->fDebugVerbose )
  1025. {
  1026. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_DebugVerbose, IDS_DNS_12945);
  1027. }
  1028. if (bReadData == FALSE)
  1029. {
  1030. // PrintDebugSz(pParams, 0, _T(" [FATAL] File %s contains invalid dns entries. Send the file to DnsDev"), pchDnsDataFileName);
  1031. PrintStatusMessage(pParams, 0, IDS_DNS_12946, pchDnsDataFileName);
  1032. pResults->Dns.fOutput = TRUE;
  1033. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  1034. IDS_DNS_12946, pchDnsDataFileName);
  1035. fRetVal = FALSE;
  1036. }
  1037. else
  1038. {
  1039. switch (Results)
  1040. {
  1041. case enumSuccess:
  1042. // IDS_DNS_12846 " PASS - All the DNS entries for DC are registered on DNS server %s.\n"
  1043. PrintStatusMessage(pParams, 0, IDS_DNS_12846, IpAddressString);
  1044. pResults->Dns.fOutput = TRUE;
  1045. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12846, IpAddressString);
  1046. fRetVal = TRUE;
  1047. break;
  1048. case enumRegistered:
  1049. // IDS_DNS_12847 " PASS - All the DNS entries for DC are registered on DNS server %s and other DCs also have some of the names registered.\n"
  1050. PrintStatusMessage(pParams, 0, IDS_DNS_12847, IpAddressString);
  1051. pResults->Dns.fOutput = TRUE;
  1052. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12847, IpAddressString);
  1053. fRetVal = TRUE;
  1054. break;
  1055. case enumTimeout:
  1056. // IDS_DNS_12850 " [WARNING] The DNS entries for this DC cannot be verified right now on DNS server %s, ERROR_TIMEOUT. \n"
  1057. PrintStatusMessage(pParams, 0, IDS_DNS_12949, IpAddressString);
  1058. pResults->Dns.fOutput = TRUE;
  1059. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12949, IpAddressString);
  1060. fRetVal = FALSE;
  1061. break;
  1062. case enumProblem:
  1063. default:
  1064. if (pParams->fFixProblems)
  1065. {
  1066. if (bFixFail == FALSE )
  1067. {
  1068. // IDS_DNS_12848 " FIX PASS - nettest re-registered missing DNS entries for this DC successfully on DNS server %s.\n"
  1069. PrintStatusMessage(pParams, 0, IDS_DNS_12848, IpAddressString);
  1070. pResults->Dns.fOutput = TRUE;
  1071. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12848, IpAddressString);
  1072. }
  1073. else
  1074. {
  1075. // IDS_DNS_12849 " [FATAL] Fix Failed: nettest failed to re-register missing DNS entries for this DC on DNS server %s.\n"
  1076. PrintStatusMessage(pParams, 0, IDS_DNS_12849, IpAddressString);
  1077. pResults->Dns.fOutput = TRUE;
  1078. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12849, IpAddressString);
  1079. }
  1080. }
  1081. else
  1082. {
  1083. // IDS_DNS_12850 " [WARNING] The DNS entries for this DC are not registered correctly on DNS server %s. Please wait for 30 minutes for DNS server replication.\n"
  1084. PrintStatusMessage(pParams, 0, IDS_DNS_12850, IpAddressString);
  1085. pResults->Dns.fOutput = TRUE;
  1086. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12850, IpAddressString);
  1087. }
  1088. fRetVal = FALSE;
  1089. }
  1090. }
  1091. Free(pDNSRecord);
  1092. return fRetVal;
  1093. }
  1094. //
  1095. // The following are for dns DC entry check
  1096. //
  1097. BOOL ReadStringToDnsRecord(
  1098. IN LPSTR lpstrString,
  1099. OUT PDNS_RECORD pDNSRecord)
  1100. /*++
  1101. Routine Description:
  1102. Parse a string and put the data into DNS record
  1103. Arguments:
  1104. lpstrString - The input string, the format is:
  1105. DnsName IN Type Data
  1106. pDNSRecord - The result DNS record
  1107. Return Value:
  1108. TRUE: if succeed. False otherwise
  1109. --*/
  1110. {
  1111. BOOL bComments;
  1112. LPSTR lpstrType,lpstrTemp;
  1113. PCHAR pchEnd;
  1114. DWORD dwTemp;
  1115. LPCTSTR pszWhite = _T(" \t\n");
  1116. // skip white spaces and comments lines
  1117. // comments start with ;
  1118. //
  1119. // Initialize pDNSRecord
  1120. //
  1121. pDNSRecord->pNext = NULL;
  1122. // Commented out to port to Source Depot - smanda
  1123. #ifdef SLM_TREE
  1124. pDNSRecord->Flags.S.Unicode = FALSE;
  1125. #endif
  1126. pDNSRecord->dwTtl = 0;
  1127. // name
  1128. pDNSRecord->pName = strtok(lpstrString, pszWhite);
  1129. if(!pDNSRecord->pName || pDNSRecord->pName[0] == _T(';'))
  1130. {
  1131. return ( FALSE );
  1132. }
  1133. // ttl: this is added since build 1631
  1134. // we need to check which format the netlogon.dns is using
  1135. lpstrTemp = strtok(NULL,pszWhite);
  1136. if (lpstrTemp)
  1137. {
  1138. dwTemp = strtoul( lpstrTemp, &pchEnd, 10 );
  1139. if ( (lpstrTemp != pchEnd) && (*pchEnd == '\0') )
  1140. {
  1141. pDNSRecord->dwTtl = dwTemp ;
  1142. // skip the class IN
  1143. strtok(NULL, pszWhite);
  1144. }
  1145. }
  1146. // type
  1147. lpstrType = strtok(NULL,pszWhite);
  1148. if (lpstrType)
  1149. {
  1150. if (_stricmp(lpstrType,_T("A")) == 0)
  1151. {
  1152. pDNSRecord->wType = DNS_TYPE_A;
  1153. pDNSRecord->wDataLength = sizeof( DNS_A_DATA );
  1154. // IP address
  1155. lpstrTemp = strtok(NULL,pszWhite);
  1156. if (lpstrTemp)
  1157. pDNSRecord->Data.A.IpAddress = inet_addr ( lpstrTemp );
  1158. }
  1159. else if (_stricmp(lpstrType,_T("SRV")) == 0)
  1160. {
  1161. pDNSRecord->wType = DNS_TYPE_SRV;
  1162. pDNSRecord->wDataLength = sizeof( DNS_SRV_DATA );
  1163. // wPriority
  1164. lpstrTemp = strtok(NULL,pszWhite);
  1165. if (lpstrTemp)
  1166. pDNSRecord->Data.SRV.wPriority = (WORD) atoi ( lpstrTemp );
  1167. // wWeight
  1168. lpstrTemp = strtok(NULL,pszWhite);
  1169. if (lpstrTemp)
  1170. pDNSRecord->Data.SRV.wWeight = (WORD) atoi ( lpstrTemp );
  1171. // wPort
  1172. lpstrTemp = strtok(NULL,pszWhite);
  1173. if (lpstrTemp)
  1174. pDNSRecord->Data.SRV.wPort = (WORD) atoi ( lpstrTemp );
  1175. // pNameTarget
  1176. pDNSRecord->Data.SRV.pNameTarget = strtok(NULL,pszWhite);
  1177. }
  1178. else if (_stricmp(lpstrType,_T("CNAME")) == 0)
  1179. {
  1180. pDNSRecord->wType = DNS_TYPE_CNAME;
  1181. pDNSRecord->wDataLength = sizeof( DNS_PTR_DATA );
  1182. // name host
  1183. pDNSRecord->Data.CNAME.pNameHost = strtok(NULL,pszWhite);
  1184. }
  1185. }
  1186. return ( TRUE );
  1187. }
  1188. VOID PrintDNSError(
  1189. NETDIAG_PARAMS *pParams,
  1190. NETDIAG_RESULT *pResults,
  1191. IN DWORD status,
  1192. NdVerbose ndv)
  1193. /*++
  1194. Routine Description:
  1195. Print out error message
  1196. Arguments:
  1197. status - error code
  1198. Return Value:
  1199. none
  1200. --*/
  1201. {
  1202. // IDS_DNS_12851 "DNS Error code: "
  1203. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12851);
  1204. switch ( status ) {
  1205. case ERROR_SUCCESS:
  1206. // IDS_DNS_12852 "ERROR_SUCCESS\n"
  1207. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12852);
  1208. break;
  1209. case DNS_ERROR_RCODE_FORMAT_ERROR :
  1210. // IDS_DNS_12853 "DNS_ERROR_RCODE_FORMAT_ERROR\n"
  1211. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12853);
  1212. break;
  1213. case DNS_ERROR_RCODE_SERVER_FAILURE :
  1214. // IDS_DNS_12854 "DNS_ERROR_RCODE_SERVER_FAILURE\n"
  1215. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12854);
  1216. break;
  1217. case DNS_ERROR_RCODE_NAME_ERROR :
  1218. // IDS_DNS_12855 "DNS_ERROR_RCODE_NAME_ERROR (Name does not exist on DNS server)\n"
  1219. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12855);
  1220. break;
  1221. case DNS_ERROR_RCODE_NOT_IMPLEMENTED :
  1222. // IDS_DNS_12856 "DNS_ERROR_RCODE_NOT_IMPLEMENTED\n"
  1223. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12856);
  1224. break;
  1225. case DNS_ERROR_RCODE_REFUSED :
  1226. // IDS_DNS_12857 "DNS_ERROR_RCODE_REFUSED\n"
  1227. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12857);
  1228. break;
  1229. case DNS_ERROR_RCODE_NOTAUTH :
  1230. // IDS_DNS_12858 "DNS_ERROR_RCODE_NOTAUTH\n"
  1231. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12858);
  1232. break;
  1233. case DNS_ERROR_TRY_AGAIN_LATER :
  1234. // IDS_DNS_12859 "DNS_ERROR_TRY_AGAIN_LATER\n"
  1235. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12859);
  1236. break;
  1237. case 0xcc000055 :
  1238. // IDS_DNS_12860 "DNS_ERROR_NOT_UNIQUE\n"
  1239. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12860);
  1240. break;
  1241. case 0x5b4:
  1242. // IDS_DNS_12861 "ERROR_TIMEOUT (Dns server may be down!)\n"
  1243. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12861);
  1244. break;
  1245. case 0x4c000030:
  1246. // IDS_DNS_12862 "DNS_INFO_NO_RECORDS\n"
  1247. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12862 );
  1248. break;
  1249. default:
  1250. // IDS_DNS_12863 "0x%.8X\n"
  1251. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12863,status);
  1252. }
  1253. }
  1254. /*
  1255. VOID
  1256. PrintARecord (
  1257. IN NETDIAG_PARAMS *pParams,
  1258. IN PDNS_RECORD pDnsRecord )
  1259. {
  1260. //IDS_DNS_12864 " A %d.%d.%d.%d\n"
  1261. PrintMessage(pParams, IDS_DNS_12864,
  1262. ((BYTE *) &pDnsRecord->Data.A.IpAddress)[0],
  1263. ((BYTE *) &pDnsRecord->Data.A.IpAddress)[1],
  1264. ((BYTE *) &pDnsRecord->Data.A.IpAddress)[2],
  1265. ((BYTE *) &pDnsRecord->Data.A.IpAddress)[3] );
  1266. }
  1267. VOID
  1268. PrintSRVRecord (
  1269. IN NETDIAG_PARAMS *pParams,
  1270. IN PDNS_RECORD pDnsRecord )
  1271. {
  1272. //IDS_DNS_12865 " SRV "
  1273. PrintMessage(pParams, IDS_DNS_12865 );
  1274. //IDS_DNS_12866 "%d %d %d %s \n"
  1275. PrintMessage(pParams, IDS_DNS_12866,
  1276. pDnsRecord->Data.SRV.wPriority,
  1277. pDnsRecord->Data.SRV.wWeight,
  1278. pDnsRecord->Data.SRV.wPort,
  1279. pDnsRecord->Data.SRV.pNameTarget );
  1280. }
  1281. VOID
  1282. PrintCNAMERecord (
  1283. IN NETDIAG_PARAMS *pParams,
  1284. IN PDNS_RECORD pDnsRecord )
  1285. {
  1286. //IDS_DNS_12867 " CNAME %s \n"
  1287. PrintMessage(pParams, IDS_DNS_12867,
  1288. pDnsRecord->Data.CNAME.pNameHost);
  1289. }
  1290. */
  1291. VOID
  1292. PrintRecord (
  1293. IN NETDIAG_PARAMS *pParams,
  1294. IN NETDIAG_RESULT *pResults,
  1295. IN PDNS_RECORD pDnsRecord,
  1296. IN NdVerbose ndv)
  1297. {
  1298. PDNS_RECORD pCur;
  1299. if (pDnsRecord==NULL)
  1300. return;
  1301. //IDS_DNS_12868 "DNS NAME = %s\n"
  1302. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12868, UTF8ToAnsi(pDnsRecord->pName));
  1303. //IDS_DNS_12869 "DNS DATA = \n"
  1304. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12869);
  1305. pCur = pDnsRecord;
  1306. while ( pCur )
  1307. {
  1308. switch( pCur->wType ){
  1309. case DNS_TYPE_A :
  1310. //IDS_DNS_12864 " A %d.%d.%d.%d\n"
  1311. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12864,
  1312. ((BYTE *) &pDnsRecord->Data.A.IpAddress)[0],
  1313. ((BYTE *) &pCur->Data.A.IpAddress)[1],
  1314. ((BYTE *) &pCur->Data.A.IpAddress)[2],
  1315. ((BYTE *) &pCur->Data.A.IpAddress)[3] );
  1316. break;
  1317. case DNS_TYPE_SRV :
  1318. //IDS_DNS_12865 " SRV "
  1319. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12865 );
  1320. //IDS_DNS_12866 "%d %d %d %s \n"
  1321. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12866,
  1322. pCur->Data.SRV.wPriority,
  1323. pCur->Data.SRV.wWeight,
  1324. pCur->Data.SRV.wPort,
  1325. pCur->Data.SRV.pNameTarget );
  1326. break;
  1327. case DNS_TYPE_CNAME :
  1328. //IDS_DNS_12867 " CNAME %s \n"
  1329. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12867,
  1330. UTF8ToAnsi(pCur->Data.CNAME.pNameHost));
  1331. break;
  1332. default :
  1333. // IDS_DNS_12870 "Don't know how to print record type %d\n"
  1334. AddMessageToList(&pResults->Dns.lmsgOutput, ndv, IDS_DNS_12870,
  1335. pCur->wType);
  1336. }
  1337. pCur = pCur->pNext;
  1338. }
  1339. }
  1340. /*!--------------------------------------------------------------------------
  1341. DnsGlobalPrint
  1342. -
  1343. Author: KennT
  1344. ---------------------------------------------------------------------------*/
  1345. void DnsGlobalPrint( NETDIAG_PARAMS* pParams,
  1346. NETDIAG_RESULT* pResults)
  1347. {
  1348. if (!pResults->IpConfig.fEnabled)
  1349. return;
  1350. if (pParams->fVerbose || !FHrOK(pResults->Dns.hr) || pResults->Dns.fOutput)
  1351. {
  1352. PrintNewLine(pParams, 2);
  1353. PrintTestTitleResult(pParams, IDS_DNS_LONG, IDS_DNS_SHORT, TRUE, pResults->Dns.hr, 0);
  1354. PrintMessageList(pParams, &pResults->Dns.lmsgOutput);
  1355. }
  1356. }
  1357. /*!--------------------------------------------------------------------------
  1358. DnsPerInterfacePrint
  1359. -
  1360. Author: KennT
  1361. ---------------------------------------------------------------------------*/
  1362. void DnsPerInterfacePrint( NETDIAG_PARAMS* pParams,
  1363. NETDIAG_RESULT* pResults,
  1364. INTERFACE_RESULT *pInterfaceResults)
  1365. {
  1366. /* BOOL fVerboseT;
  1367. BOOL fReallyVerboseT;
  1368. if (!pResults->IpConfig.fEnabled)
  1369. return;
  1370. if (!pInterfaceResults->IpConfig.fActive)
  1371. return;
  1372. if (pParams->fVerbose || pInterfaceResults->Dns.fOutput)
  1373. {
  1374. fVerboseT = pParams->fVerbose;
  1375. fReallyVerboseT = pParams->fReallyVerbose;
  1376. pParams->fReallyVerbose = TRUE;
  1377. PrintNewLine(pParams, 1);
  1378. //IDS_DNS_12871 " DNS test results :\n"
  1379. PrintMessage(pParams, IDS_DNS_12871);
  1380. PrintMessageList(pParams, &pInterfaceResults->Dns.lmsgOutput);
  1381. pParams->fReallyVerbose = fReallyVerboseT;
  1382. pParams->fVerbose = fVerboseT;
  1383. }
  1384. */
  1385. return;
  1386. }
  1387. /*!--------------------------------------------------------------------------
  1388. DnsCleanup
  1389. -
  1390. Author: KennT
  1391. ---------------------------------------------------------------------------*/
  1392. void DnsCleanup( NETDIAG_PARAMS* pParams, NETDIAG_RESULT* pResults)
  1393. {
  1394. int i;
  1395. MessageListCleanUp(&pResults->Dns.lmsgOutput);
  1396. for ( i=0; i<pResults->cNumInterfaces; i++)
  1397. {
  1398. MessageListCleanUp(&pResults->pArrayInterface[i].Dns.lmsgOutput);
  1399. }
  1400. }