Leaked source code of windows server 2003
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.

1723 lines
58 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1998-2002
  3. Module Name:
  4. dnscmn.c
  5. Abstract:
  6. Domain Name System (DNS) Netdiag Tests
  7. Author:
  8. Elena Apreutesei (elenaap) 10/22/98
  9. Revision History:
  10. jamesg May 2002 -- cleanup for network info changes
  11. jamesg Sept 2000 -- more scrub and cleanup
  12. --*/
  13. #include "precomp.h"
  14. #include "dnscmn.h"
  15. #include <malloc.h>
  16. LPSTR
  17. UTF8ToAnsi(
  18. IN PSTR szuStr
  19. )
  20. //
  21. // note this is not MT safe
  22. //
  23. {
  24. WCHAR wszBuff[2048];
  25. static CHAR aszBuff[2048];
  26. strcpy( aszBuff, "" );
  27. if ( !szuStr )
  28. {
  29. return aszBuff;
  30. }
  31. if ( MultiByteToWideChar(
  32. CP_UTF8,
  33. 0L,
  34. szuStr,
  35. -1,
  36. wszBuff,
  37. DimensionOf(wszBuff)
  38. ))
  39. {
  40. WideCharToMultiByte(
  41. CP_ACP,
  42. 0L,
  43. wszBuff,
  44. -1,
  45. aszBuff,
  46. DimensionOf(aszBuff),
  47. NULL,
  48. NULL);
  49. }
  50. return aszBuff;
  51. }
  52. HRESULT
  53. CheckDnsRegistration(
  54. IN PDNS_NETINFO pNetworkInfo,
  55. OUT NETDIAG_PARAMS * pParams,
  56. OUT NETDIAG_RESULT * pResults
  57. )
  58. {
  59. LPSTR pszHostName = NULL;
  60. LPSTR pszPrimaryDomain = NULL;
  61. LPSTR pszDomain = NULL;
  62. IP4_ADDRESS dwServerIP;
  63. IP4_ADDRESS dwIP;
  64. INT idx;
  65. INT idx1;
  66. INT idx2;
  67. BOOL RegDnOk;
  68. BOOL RegPdnOk;
  69. BOOL RegDnAll;
  70. BOOL RegPdnAll;
  71. char szName[DNS_MAX_NAME_BUFFER_LENGTH];
  72. char szIP[1500];
  73. DNS_RECORD recordA[MAX_ADDRS];
  74. DNS_RECORD recordPTR;
  75. DNS_STATUS status;
  76. PREGISTRATION_INFO pExpectedRegistration = NULL;
  77. HRESULT hResult = hrOK;
  78. DNSDBG( TRACE, (
  79. "\n\nNETDIAG: CheckDnsRegistration( %p )\n\n",
  80. pNetworkInfo
  81. ));
  82. // print out DNS settings
  83. pszHostName = (PSTR) DnsQueryConfigAlloc(
  84. DnsConfigHostName_UTF8,
  85. NULL );
  86. if (NULL == pszHostName)
  87. {
  88. //IDS_DNS_NO_HOSTNAME " [FATAL] Cannot find DNS host name."
  89. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_NO_HOSTNAME);
  90. hResult = S_FALSE;
  91. goto L_ERROR;
  92. }
  93. pszPrimaryDomain = (PSTR) DnsQueryConfigAlloc(
  94. DnsConfigPrimaryDomainName_UTF8,
  95. NULL );
  96. // compute the expected DNS registration
  97. status = ComputeExpectedRegistration(
  98. pszHostName,
  99. pszPrimaryDomain,
  100. pNetworkInfo,
  101. &pExpectedRegistration,
  102. pParams,
  103. pResults);
  104. // verifies the DNS registration
  105. if (pExpectedRegistration)
  106. hResult = VerifyDnsRegistration(
  107. pszHostName,
  108. pExpectedRegistration,
  109. pParams,
  110. pResults);
  111. L_ERROR:
  112. return hResult;
  113. }
  114. DNS_STATUS
  115. ComputeExpectedRegistration(
  116. IN LPSTR pszHostName,
  117. IN LPSTR pszPrimaryDomain,
  118. IN PDNS_NETINFO pNetworkInfo,
  119. OUT PREGISTRATION_INFO * ppExpectedRegistration,
  120. OUT NETDIAG_PARAMS * pParams,
  121. OUT NETDIAG_RESULT * pResults
  122. )
  123. {
  124. DWORD idx;
  125. DWORD idx1;
  126. DNS_STATUS status;
  127. char szName[DNS_MAX_NAME_BUFFER_LENGTH];
  128. PDNS_NETINFO pFazResult = NULL;
  129. LPSTR pszDomain;
  130. DWORD dwIP;
  131. PIP4_ARRAY pDnsServers = NULL;
  132. PIP4_ARRAY pNameServers = NULL;
  133. PIP4_ARRAY pNS = NULL;
  134. IP4_ARRAY PrimaryDNS;
  135. LPWSTR pwAdapterGuidName = NULL;
  136. BOOL bRegEnabled = FALSE;
  137. BOOL bAdapterRegEnabled = FALSE;
  138. DNSDBG( TRACE, (
  139. "\n\nNETDIAG: ComputeExpectedRegistration( %s, %s, %p )\n\n",
  140. pszHostName,
  141. pszPrimaryDomain,
  142. pNetworkInfo
  143. ));
  144. *ppExpectedRegistration = NULL;
  145. for (idx = 0; idx < pNetworkInfo->AdapterCount; idx++)
  146. {
  147. PDNS_ADAPTER padapter = pNetworkInfo->AdapterArray[idx];
  148. //IDS_DNS_12878 " Interface %s\n"
  149. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12878, padapter->pszAdapterGuidName);
  150. pszDomain = padapter->pszAdapterDomain;
  151. //IDS_DNS_12879 " DNS Domain: %s\n"
  152. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12879, UTF8ToAnsi(pszDomain));
  153. //IDS_DNS_12880 " DNS Servers: "
  154. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12880);
  155. for (idx1 = 0; idx1 < padapter->ServerCount; idx1++)
  156. {
  157. dwIP = padapter->ServerArray[idx1].IpAddress;
  158. //IDS_DNS_12881 "%s "
  159. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12881, IP_STRING(dwIP));
  160. }
  161. //IDS_DNS_12882 "\n IP Address: "
  162. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12882);
  163. #if 0
  164. //
  165. // DCR: local addresses now kept as DNS_ADDR
  166. //
  167. if( (pNetworkInfo->AdapterArray[0])->pAdapterIPAddresses )
  168. {
  169. for(idx1 = 0; idx1 < padapter->pAdapterIPAddresses->AddrCount; idx1++)
  170. {
  171. dwIP = padapter->pAdapterIPAddresses->AddrArray[idx1];
  172. //IDS_DNS_12883 "%s "
  173. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12883, IP_STRING(dwIP));
  174. }
  175. //IDS_DNS_12884 "\n"
  176. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12884);
  177. }
  178. #endif
  179. pDnsServers = ServerInfoToIpArray(
  180. padapter->ServerCount,
  181. padapter->ServerArray
  182. );
  183. //
  184. // Verify if DNS registration is enabled for interface and for adapter's DNS domain name
  185. //
  186. bRegEnabled = bAdapterRegEnabled = FALSE;
  187. pwAdapterGuidName = LocalAlloc(LPTR, sizeof(WCHAR)*(1+strlen(padapter->pszAdapterGuidName)));
  188. if (pwAdapterGuidName)
  189. {
  190. MultiByteToWideChar(
  191. CP_ACP,
  192. 0L,
  193. padapter->pszAdapterGuidName,
  194. -1,
  195. pwAdapterGuidName,
  196. sizeof(WCHAR)*(1+strlen(padapter->pszAdapterGuidName))
  197. );
  198. bRegEnabled = (BOOL) DnsQueryConfigDword(
  199. DnsConfigRegistrationEnabled,
  200. pwAdapterGuidName );
  201. bAdapterRegEnabled = (BOOL) DnsQueryConfigDword(
  202. DnsConfigAdapterHostNameRegistrationEnabled,
  203. pwAdapterGuidName );
  204. LocalFree(pwAdapterGuidName);
  205. }
  206. if(bRegEnabled)
  207. {
  208. if(pDnsServers)
  209. {
  210. // compute expected registration with PDN
  211. if (pszPrimaryDomain && strlen(pszPrimaryDomain))
  212. {
  213. sprintf(szName, "%s.%s.", pszHostName, pszPrimaryDomain);
  214. //
  215. // aVOID double dot terminated name
  216. // - can happen with explicit dot-terminated primary name
  217. {
  218. DWORD length = strlen( szName );
  219. if ( length >= 2 &&
  220. szName[ length-2 ] == '.' )
  221. {
  222. szName[ length-1 ] = 0;
  223. }
  224. }
  225. //IDS_DNS_12886 " Expected registration with PDN (primary DNS domain name):\n Hostname: %s\n"
  226. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12886, UTF8ToAnsi(szName));
  227. pFazResult = NULL;
  228. pNameServers = NULL;
  229. status = DnsFindAllPrimariesAndSecondaries(
  230. szName,
  231. DNS_QUERY_BYPASS_CACHE,
  232. pDnsServers,
  233. &pFazResult,
  234. &pNameServers,
  235. NULL);
  236. if (pFazResult)
  237. {
  238. //IDS_DNS_12887 " Authoritative zone: %s\n"
  239. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12887,
  240. UTF8ToAnsi(pFazResult->pSearchList->pszDomainOrZoneName));
  241. //IDS_DNS_12888 " Primary DNS server: %s %s\n"
  242. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12888, UTF8ToAnsi(pFazResult->AdapterArray[0]->pszAdapterDomain),
  243. IP_STRING(pFazResult->AdapterArray[0]->ServerArray[0].IpAddress));
  244. if (pNameServers)
  245. {
  246. //IDS_DNS_12889 " Authoritative NS:"
  247. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12889);
  248. for(idx1=0; idx1 < pNameServers->AddrCount; idx1++)
  249. //IDS_DNS_12890 "%s "
  250. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12890,
  251. IP_STRING(pNameServers->AddrArray[idx1]));
  252. //IDS_DNS_12891 "\n"
  253. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12891);
  254. pNS = pNameServers;
  255. }
  256. else
  257. {
  258. //IDS_DNS_12892 " NS query failed with %d %s\n"
  259. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12892, status, DnsStatusString(status));
  260. PrimaryDNS.AddrCount = 1;
  261. PrimaryDNS.AddrArray[0] = pFazResult->AdapterArray[0]->ServerArray[0].IpAddress;
  262. pNS = &PrimaryDNS;
  263. }
  264. status = DnsUpdateAllowedTest_UTF8(
  265. NULL,
  266. szName,
  267. pFazResult->pSearchList->pszDomainOrZoneName,
  268. pNS);
  269. if ((status == NO_ERROR) || (status == ERROR_TIMEOUT))
  270. AddToExpectedRegistration(
  271. pszPrimaryDomain,
  272. padapter,
  273. pFazResult,
  274. pNS,
  275. ppExpectedRegistration);
  276. else
  277. //IDS_DNS_12893 " Update is not allowed in zone %s.\n"
  278. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12893, UTF8ToAnsi(pFazResult->pSearchList->pszDomainOrZoneName));
  279. }
  280. else
  281. {
  282. //IDS_DNS_12894 " [WARNING] Cannot find the authoritative server for the DNS name '%s'. [%s]\n The name '%s' may not be registered properly on the DNS servers.\n"
  283. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12894, UTF8ToAnsi(szName), DnsStatusString(status), UTF8ToAnsi(szName));
  284. }
  285. }
  286. // compute expected registration with DN for this adapter
  287. if (pszDomain && strlen(pszDomain) &&
  288. (!pszPrimaryDomain || !strlen(pszPrimaryDomain) ||
  289. (pszPrimaryDomain && pszDomain && _stricmp(pszDomain, pszPrimaryDomain))))
  290. {
  291. sprintf(szName, "%s.%s." , pszHostName, pszDomain);
  292. //
  293. // aVOID double dot terminated name
  294. // - can happen with explicit dot-terminated domain name
  295. {
  296. DWORD length = strlen( szName );
  297. if ( length >= 2 &&
  298. szName[ length-2 ] == '.' )
  299. {
  300. szName[ length-1 ] = 0;
  301. }
  302. }
  303. //IDS_DNS_12896 " Expected registration with adapter's DNS Domain Name:\n Hostname: %s\n"
  304. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12896, UTF8ToAnsi(szName));
  305. if (bAdapterRegEnabled)
  306. {
  307. pFazResult = NULL;
  308. pNameServers = NULL;
  309. status = DnsFindAllPrimariesAndSecondaries(
  310. szName,
  311. DNS_QUERY_BYPASS_CACHE,
  312. pDnsServers,
  313. &pFazResult,
  314. &pNameServers,
  315. NULL);
  316. if (pFazResult)
  317. {
  318. //IDS_DNS_12897 " Authoritative zone: %s\n"
  319. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12897, UTF8ToAnsi(pFazResult->pSearchList->pszDomainOrZoneName));
  320. //IDS_DNS_12898 " Primary DNS server: %s %s\n"
  321. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12898, UTF8ToAnsi(pFazResult->AdapterArray[0]->pszAdapterDomain),
  322. IP_STRING(pFazResult->AdapterArray[0]->ServerArray[0].IpAddress));
  323. if (pNameServers)
  324. {
  325. //IDS_DNS_12899 " Authoritative NS:"
  326. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12899);
  327. for(idx1=0; idx1 < pNameServers->AddrCount; idx1++)
  328. //IDS_DNS_12900 "%s "
  329. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12900,
  330. IP_STRING(pNameServers->AddrArray[idx1]));
  331. //IDS_DNS_12901 "\n"
  332. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12901);
  333. pNS = pNameServers;
  334. }
  335. else
  336. {
  337. //IDS_DNS_12902 " NS query failed with %d %s\n"
  338. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12902, status, DnsStatusString(status));
  339. PrimaryDNS.AddrCount = 1;
  340. PrimaryDNS.AddrArray[0] = pFazResult->AdapterArray[0]->ServerArray[0].IpAddress;
  341. pNS = &PrimaryDNS;
  342. }
  343. status = DnsUpdateAllowedTest_UTF8(
  344. NULL,
  345. szName,
  346. pFazResult->pSearchList->pszDomainOrZoneName,
  347. pNS);
  348. if ((status == NO_ERROR) || (status == ERROR_TIMEOUT))
  349. AddToExpectedRegistration(
  350. pszDomain,
  351. padapter,
  352. pFazResult,
  353. pNS,
  354. ppExpectedRegistration);
  355. else
  356. //IDS_DNS_12903 " Update is not allowed in zone %s\n"
  357. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12903, UTF8ToAnsi(pFazResult->pSearchList->pszDomainOrZoneName));
  358. }
  359. else
  360. {
  361. //IDS_DNS_12894 " [WARNING] Cannot find the authoritative server for the DNS name '%s'. [%s]\n The name '%s' may not be registered properly on the DNS servers.\n"
  362. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, IDS_DNS_12894, UTF8ToAnsi(szName), DnsStatusString(status), UTF8ToAnsi(szName));
  363. }
  364. }
  365. else
  366. {
  367. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12939);
  368. }
  369. }
  370. LocalFree(pDnsServers);
  371. }
  372. }
  373. else // if(bRegEnabled)
  374. {
  375. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12947);
  376. }
  377. }
  378. return NO_ERROR;
  379. }
  380. VOID
  381. AddToExpectedRegistration(
  382. IN LPSTR pszDomain,
  383. IN PDNS_ADAPTER pAdapterInfo,
  384. IN PDNS_NETINFO pFazResult,
  385. IN PIP4_ARRAY pNS,
  386. OUT PREGISTRATION_INFO * ppExpectedRegistration
  387. )
  388. {
  389. #if 0
  390. //
  391. // DCR: local addresses now kept as DNS_ADDR
  392. //
  393. // note, this function doesn't seem to work anyway as the test below
  394. // for existence of pAdapterInfo->pAdapterIPAddresses is backwards
  395. //
  396. PREGISTRATION_INFO pCurrent = *ppExpectedRegistration;
  397. PREGISTRATION_INFO pNew = NULL;
  398. PREGISTRATION_INFO pLast = NULL;
  399. BOOL done = FALSE;
  400. BOOL found = FALSE;
  401. DWORD i,j;
  402. IP4_ARRAY ipArray;
  403. DWORD dwAddrToRegister = 0;
  404. DWORD dwMaxAddrToRegister;
  405. USES_CONVERSION;
  406. dwMaxAddrToRegister = DnsQueryConfigDword(
  407. DnsConfigAddressRegistrationMaxCount,
  408. A2W(pAdapterInfo->pszAdapterGuidName ));
  409. if( pAdapterInfo->pAdapterIPAddresses )
  410. {
  411. // It might be NULL
  412. return;
  413. }
  414. dwAddrToRegister = (pAdapterInfo->pAdapterIPAddresses->AddrCount < dwMaxAddrToRegister) ?
  415. pAdapterInfo->pAdapterIPAddresses->AddrCount : dwMaxAddrToRegister;
  416. while(pCurrent)
  417. {
  418. if(!done &&
  419. !_stricmp(pCurrent->szDomainName, pszDomain) &&
  420. !_stricmp(pCurrent->szAuthoritativeZone, pFazResult->pSearchList->pszDomainOrZoneName) &&
  421. SameAuthoritativeServers(pCurrent, pNS))
  422. {
  423. // found a node under the same domain name / authoritative server list
  424. done = TRUE;
  425. if(pCurrent->dwIPCount + pAdapterInfo->pAdapterIPAddresses->AddrCount > MAX_ADDRS)
  426. {
  427. //IDS_DNS_12905 " WARNING - more than %d IP addresses\n"
  428. // AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Verbose, IDS_DNS_12905, MAX_ADDRS);
  429. return;
  430. }
  431. // add the new IPs
  432. for(i=0; i < dwAddrToRegister; i++)
  433. {
  434. pCurrent->IPAddresses[pCurrent->dwIPCount + i] = pAdapterInfo->pAdapterIPAddresses->AddrArray[i];
  435. }
  436. pCurrent->dwIPCount += dwAddrToRegister;
  437. // for each NS check if it's already in the list, if not add it
  438. for(i=0; i < pNS->AddrCount; i++)
  439. {
  440. found = FALSE;
  441. for(j=0; !found && (j < pCurrent->dwAuthNSCount); j++)
  442. if(pNS->AddrArray[i] == pCurrent->AuthoritativeNS[j])
  443. found = TRUE;
  444. if (!found && pCurrent->dwAuthNSCount < MAX_NAME_SERVER_COUNT)
  445. pCurrent->AuthoritativeNS[pCurrent->dwAuthNSCount++] = pNS->AddrArray[i];
  446. }
  447. // check if DNS servers allow updates
  448. if (pCurrent->AllowUpdates == ERROR_TIMEOUT)
  449. {
  450. ipArray.AddrCount = 1;
  451. ipArray.AddrArray[0] = pFazResult->AdapterArray[0]->ServerArray[0].IpAddress;
  452. pCurrent->AllowUpdates = DnsUpdateTest_UTF8(
  453. NULL, // Context handle
  454. pCurrent->szAuthoritativeZone,
  455. 0, //DNS_UPDATE_TEST_USE_LOCAL_SYS_ACCT,
  456. &ipArray); // use the DNS server returned from FAZ
  457. }
  458. }
  459. pLast = pCurrent;
  460. pCurrent = pCurrent->pNext;
  461. }
  462. if (!done)
  463. {
  464. // need to allocate new entry
  465. pNew = LocalAlloc(LMEM_FIXED, sizeof(REGISTRATION_INFO));
  466. if( !pNew)
  467. return;
  468. pNew->pNext = NULL;
  469. strcpy(pNew->szDomainName, pszDomain);
  470. strcpy(pNew->szAuthoritativeZone, pFazResult->pSearchList->pszDomainOrZoneName);
  471. pNew->dwIPCount = 0;
  472. for(i=0; i < dwAddrToRegister; i++)
  473. {
  474. if(pNew->dwIPCount < MAX_ADDRS)
  475. pNew->IPAddresses[pNew->dwIPCount++] = pAdapterInfo->pAdapterIPAddresses->AddrArray[i];
  476. else
  477. {
  478. //IDS_DNS_12905 " WARNING - more than %d IP addresses\n"
  479. // AddMessageToList(&pResults->Dns.lmsgOutput, Nd_Verbose, IDS_DNS_12905, MAX_ADDRS);
  480. break;
  481. }
  482. }
  483. pNew->dwAuthNSCount = 0;
  484. for(i=0; i < pNS->AddrCount; i++)
  485. {
  486. if (pNew->dwAuthNSCount < MAX_NAME_SERVER_COUNT)
  487. pNew->AuthoritativeNS[pNew->dwAuthNSCount++] = pNS->AddrArray[i];
  488. else
  489. break;
  490. }
  491. // check if DNS servers allow updates
  492. ipArray.AddrCount = 1;
  493. ipArray.AddrArray[0] = pFazResult->AdapterArray[0]->ServerArray[0].IpAddress;
  494. pNew->AllowUpdates = DnsUpdateTest_UTF8(
  495. NULL, // Context handle
  496. pNew->szAuthoritativeZone,
  497. 0, //DNS_UPDATE_TEST_USE_LOCAL_SYS_ACCT,
  498. &ipArray); // use the DNS server returned from FAZ
  499. if(pLast)
  500. pLast->pNext = (LPVOID)pNew;
  501. else
  502. *ppExpectedRegistration = pNew;
  503. }
  504. #endif
  505. }
  506. BOOL
  507. SameAuthoritativeServers(
  508. IN PREGISTRATION_INFO pCurrent,
  509. IN PIP4_ARRAY pNS
  510. )
  511. {
  512. BOOL same = FALSE, found = FALSE;
  513. DWORD i, j;
  514. for (i=0; i<pCurrent->dwAuthNSCount; i++)
  515. {
  516. found = FALSE;
  517. for (j=0; j<pNS->AddrCount; j++)
  518. if(pNS->AddrArray[j] == pCurrent->AuthoritativeNS[i])
  519. found = TRUE;
  520. if (found)
  521. same = TRUE;
  522. }
  523. return same;
  524. }
  525. HRESULT
  526. VerifyDnsRegistration(
  527. IN LPSTR pszHostName,
  528. IN PREGISTRATION_INFO pExpectedRegistration,
  529. IN NETDIAG_PARAMS * pParams,
  530. IN OUT NETDIAG_RESULT * pResults
  531. )
  532. {
  533. PREGISTRATION_INFO pCurrent = pExpectedRegistration;
  534. BOOL regOne;
  535. BOOL regAll;
  536. BOOL partialMatch;
  537. DWORD i;
  538. DWORD j;
  539. DWORD numOfMissingAddr;
  540. DNS_STATUS status;
  541. PDNS_RECORD pExpected=NULL;
  542. PDNS_RECORD pDiff1=NULL;
  543. PDNS_RECORD pDiff2=NULL;
  544. PDNS_RECORD pThis = NULL;
  545. char szFqdn[DNS_MAX_NAME_BUFFER_LENGTH];
  546. IP4_ARRAY DnsServer;
  547. HRESULT hr = hrOK;
  548. DNSDBG( TRACE, (
  549. "\n\nNETDIAG: VerifyDnsRegistration( %s, reg=%p )\n\n",
  550. pszHostName,
  551. pExpectedRegistration ));
  552. //IDS_DNS_12906 " Verify DNS registration:\n"
  553. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12906);
  554. DnsServer.AddrCount = 1;
  555. while(pCurrent)
  556. {
  557. regOne = FALSE; regAll = TRUE;
  558. partialMatch = FALSE;
  559. numOfMissingAddr = 0;
  560. sprintf(szFqdn, "%s.%s" , pszHostName, pCurrent->szDomainName);
  561. //IDS_DNS_12908 " Name: %s\n"
  562. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12908, UTF8ToAnsi(szFqdn));
  563. // build the expected RRset
  564. pExpected = LocalAlloc(LMEM_FIXED, pCurrent->dwIPCount * sizeof(DNS_RECORD));
  565. if(!pExpected)
  566. {
  567. //IDS_DNS_12909 " LocalAlloc() failed, exit verify\n"
  568. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12909);
  569. return S_FALSE;
  570. }
  571. memset(pExpected, 0, pCurrent->dwIPCount * sizeof(DNS_RECORD));
  572. //IDS_DNS_12910 " Expected IP: "
  573. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12910);
  574. for (j=0; j<pCurrent->dwIPCount; j++)
  575. {
  576. pExpected[j].pName = szFqdn;
  577. pExpected[j].wType = DNS_TYPE_A;
  578. pExpected[j].wDataLength = sizeof(DNS_A_DATA);
  579. pExpected[j].Data.A.IpAddress = pCurrent->IPAddresses[j];
  580. pExpected[j].pNext = (j < (pCurrent->dwIPCount - 1))?(&pExpected[j+1]):NULL;
  581. pExpected[j].Flags.S.Section = DNSREC_ANSWER;
  582. //IDS_DNS_12911 "%s "
  583. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12911, IP_STRING(pCurrent->IPAddresses[j]));
  584. }
  585. //IDS_DNS_12912 "\n"
  586. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12912);
  587. // verify on each server
  588. for (i=0; i < pCurrent->dwAuthNSCount; i++)
  589. {
  590. DnsServer.AddrArray[0] = pCurrent->AuthoritativeNS[i];
  591. /*
  592. //
  593. // Ping the DNS server.
  594. //
  595. IpAddressString = inet_ntoa(inetDnsServer.AddrArray[0]);
  596. if ( IpAddressString )
  597. if (!IsIcmpResponseA( IpAddressString )
  598. {
  599. PrintStatusMessage(pParams, 12, IDS_DNS_CANNOT_PING, IpAddressString);
  600. pIfResults->Dns.fOutput = TRUE;
  601. AddIMessageToList(&pIfResults->Dns.lmsgOutput, Nd_Quiet, 16,
  602. IDS_DNS_CANNOT_PING, IpAddressString);
  603. RetVal = FALSE;
  604. goto Cleanup;
  605. }
  606. */
  607. pDiff1 = pDiff2 = NULL;
  608. status = DnsQueryAndCompare(
  609. szFqdn,
  610. DNS_TYPE_A,
  611. DNS_QUERY_DATABASE,
  612. &DnsServer,
  613. NULL, // no record results
  614. NULL, // don't want the full DNS message
  615. pExpected,
  616. FALSE,
  617. FALSE,
  618. &pDiff1,
  619. &pDiff2
  620. );
  621. if(status != NO_ERROR)
  622. {
  623. if (status == ERROR_NO_MATCH)
  624. {
  625. //IDS_DNS_12913 " Server %s: ERROR_NO_MATCH\n"
  626. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12913,
  627. IP_STRING(DnsServer.AddrArray[0]));
  628. if(pDiff2)
  629. {
  630. //IDS_DNS_12914 " Missing IP from DNS: "
  631. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12914);
  632. for (pThis = pDiff2; pThis; pThis = pThis->pNext, numOfMissingAddr++)
  633. //IDS_DNS_12915 "%s "
  634. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12915, IP_STRING (pThis->Data.A.IpAddress));
  635. //IDS_DNS_12916 "\n"
  636. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12916);
  637. if (numOfMissingAddr != pCurrent->dwIPCount)
  638. partialMatch = TRUE;
  639. }
  640. if(pDiff1)
  641. {
  642. //IDS_DNS_12917 " Wrong IP in DNS: "
  643. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12917);
  644. for (pThis = pDiff1; pThis; pThis = pThis->pNext)
  645. //IDS_DNS_12918 "%s "
  646. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12918, IP_STRING (pThis->Data.A.IpAddress));
  647. //IDS_DNS_12919 "\n"
  648. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12919);
  649. }
  650. }
  651. else
  652. //IDS_DNS_12920 " Server %s: Error %d %s\n"
  653. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12920,
  654. IP_STRING(DnsServer.AddrArray[0]), status, DnsStatusToErrorString_A(status));
  655. if ( status != ERROR_TIMEOUT )
  656. regAll = FALSE;
  657. }
  658. else
  659. {
  660. //IDS_DNS_12921 " Server %s: NO_ERROR\n"
  661. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12921,
  662. IP_STRING(DnsServer.AddrArray[0]));
  663. regOne = TRUE;
  664. }
  665. }
  666. if (regOne && !regAll)
  667. //IDS_DNS_12922 " WARNING: The DNS registration is correct only on some DNS servers, pls. wait 15 min for replication and try this test again\n"
  668. {
  669. PrintStatusMessage(pParams, 0, IDS_DNS_12922, UTF8ToAnsi(szFqdn));
  670. pResults->Dns.fOutput = TRUE;
  671. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  672. IDS_DNS_12922, UTF8ToAnsi(szFqdn));
  673. }
  674. if (!regOne && !regAll && !partialMatch)
  675. //IDS_DNS_12923 " FATAL: The DNS registration is incorrect on all DNS servers.\n"
  676. {
  677. PrintStatusMessage(pParams, 0, IDS_DNS_12923, UTF8ToAnsi(szFqdn));
  678. pResults->Dns.fOutput = TRUE;
  679. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  680. IDS_DNS_12923, UTF8ToAnsi(szFqdn));
  681. hr = S_FALSE;
  682. }
  683. if (!regOne && !regAll && partialMatch)
  684. //IDS_DNS_12951 " [WARNING] Not all DNS registrations for %s is correct on all DNS Servers. Please run netdiag /v /test:dns for more detail. \n"
  685. {
  686. PrintStatusMessage(pParams, 0, IDS_DNS_12951, UTF8ToAnsi(szFqdn));
  687. pResults->Dns.fOutput = TRUE;
  688. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  689. IDS_DNS_12951, UTF8ToAnsi(szFqdn));
  690. hr = S_FALSE;
  691. }
  692. if (!regOne && regAll)
  693. //IDS_DNS_12924 " FATAL: All DNS servers are currently down.\n"
  694. {
  695. PrintStatusMessage(pParams, 0, IDS_DNS_12924, UTF8ToAnsi(szFqdn));
  696. pResults->Dns.fOutput = TRUE;
  697. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_Quiet, 4,
  698. IDS_DNS_12924, UTF8ToAnsi(szFqdn));
  699. hr = S_FALSE;
  700. }
  701. if (regOne && regAll)
  702. {
  703. PrintStatusMessage(pParams, 6, IDS_DNS_12940, UTF8ToAnsi(szFqdn));
  704. AddIMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, 0,
  705. IDS_DNS_12940, UTF8ToAnsi(szFqdn));
  706. }
  707. pCurrent = pCurrent->pNext;
  708. }
  709. return hr;
  710. }
  711. PIP4_ARRAY
  712. ServerInfoToIpArray(
  713. IN DWORD ServerCount,
  714. IN PDNS_SERVER_INFO ServerArray
  715. )
  716. {
  717. PIP4_ARRAY pipDnsServers = NULL;
  718. DWORD i;
  719. pipDnsServers = LocalAlloc(LMEM_FIXED, IP4_ARRAY_SIZE(ServerCount));
  720. if (!pipDnsServers)
  721. {
  722. return NULL;
  723. }
  724. pipDnsServers->AddrCount = ServerCount;
  725. for (i=0; i < ServerCount; i++)
  726. {
  727. pipDnsServers->AddrArray[i] = ServerArray[i].IpAddress;
  728. }
  729. return pipDnsServers;
  730. }
  731. DNS_STATUS
  732. DnsFindAllPrimariesAndSecondaries(
  733. IN LPSTR pszName,
  734. IN DWORD dwFlags,
  735. IN PIP4_ARRAY aipQueryServers,
  736. OUT PDNS_NETINFO * ppNetworkInfo,
  737. OUT PIP4_ARRAY * ppNameServers,
  738. OUT PIP4_ARRAY * ppPrimaries
  739. )
  740. {
  741. DNS_STATUS status;
  742. PDNS_RECORD pDnsRecord = NULL;
  743. PIP4_ARRAY pDnsServers = NULL;
  744. DWORD i;
  745. DNSDBG( TRACE, (
  746. "\nNETDIAG: DnsFindAllPrimariesAndSecondaries( %s, %08x, serv==%p )\n\n",
  747. pszName,
  748. dwFlags,
  749. aipQueryServers ));
  750. //
  751. // check arguments \ init OUT params
  752. //
  753. if (!pszName || !ppNetworkInfo || !ppNameServers)
  754. return ERROR_INVALID_PARAMETER;
  755. *ppNameServers = NULL;
  756. *ppNetworkInfo = NULL;
  757. //
  758. // FAZ
  759. //
  760. status = DnsNetworkInformation_CreateFromFAZ(
  761. pszName,
  762. dwFlags,
  763. aipQueryServers,
  764. ppNetworkInfo );
  765. if ( status != NO_ERROR )
  766. {
  767. return status;
  768. }
  769. //
  770. // Get all NS records for the Authoritative Domain Name
  771. //
  772. pDnsServers = ServerInfoToIpArray(
  773. ((*ppNetworkInfo)->AdapterArray[0])->ServerCount,
  774. ((*ppNetworkInfo)->AdapterArray[0])->ServerArray
  775. );
  776. status = DnsQuery_UTF8(
  777. (*ppNetworkInfo)->pSearchList->pszDomainOrZoneName,
  778. DNS_TYPE_NS,
  779. DNS_QUERY_BYPASS_CACHE,
  780. aipQueryServers,
  781. &pDnsRecord,
  782. NULL);
  783. if (status != NO_ERROR)
  784. return status;
  785. *ppNameServers = GrabNameServersIp(pDnsRecord);
  786. //
  787. // select primaries
  788. //
  789. if (ppPrimaries)
  790. {
  791. *ppPrimaries = NULL;
  792. if (*ppNameServers)
  793. {
  794. *ppPrimaries = LocalAlloc(LPTR, IP4_ARRAY_SIZE((*ppNameServers)->AddrCount));
  795. if(*ppPrimaries)
  796. {
  797. (*ppPrimaries)->AddrCount = 0;
  798. for (i=0; i<(*ppNameServers)->AddrCount; i++)
  799. if(NO_ERROR == IsDnsServerPrimaryForZone_UTF8(
  800. (*ppNameServers)->AddrArray[i],
  801. pszName))
  802. {
  803. (*ppPrimaries)->AddrArray[(*ppPrimaries)->AddrCount] = (*ppNameServers)->AddrArray[i];
  804. ((*ppPrimaries)->AddrCount)++;
  805. }
  806. }
  807. }
  808. }
  809. return status;
  810. }
  811. /*
  812. VOID
  813. CompareCachedAndRegistryNetworkInfo(PDNS_NETINFO pNetworkInfo)
  814. {
  815. DNS_STATUS status1, status2;
  816. PDNS_RPC_ADAPTER_INFO pRpcAdapterInfo = NULL, pCurrentCache;
  817. PDNS_RPC_SERVER_INFO pRpcServer = NULL;
  818. PDNS_ADAPTER pCurrentRegistry;
  819. PDNS_IP_ADDR_LIST pIpList = NULL;
  820. BOOL cacheOk = TRUE, sameServers = TRUE, serverFound = FALSE;
  821. DWORD iCurrentAdapter, iServer, count = 0;
  822. status1 = GetCachedAdapterInfo( &pRpcAdapterInfo );
  823. status2 = GetCachedIpAddressList( &pIpList );
  824. //IDS_DNS_12925 "\nCheck DNS cached network info: \n"
  825. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12925);
  826. if(status1)
  827. {
  828. //IDS_DNS_12926 " ERROR: CRrGetAdapterInfo() failed with error %d %s\n"
  829. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12926, status1, DnsStatusToErrorString_A(status1) );
  830. return;
  831. }
  832. if (!pRpcAdapterInfo)
  833. {
  834. //IDS_DNS_12927 " ERROR: CRrGetAdapterInfo() returned NO_ERROR but empty Adapter Info\n"
  835. AddMessageToList(&pResults->Dns.lmsgOutput, Nd_ReallyVerbose, IDS_DNS_12927);
  836. return;
  837. }
  838. // check adapter count
  839. count = 0;
  840. for(pCurrentCache = pRpcAdapterInfo; pCurrentCache; pCurrentCache = pCurrentCache->pNext)
  841. count++;
  842. if(count != pNetworkInfo->AdapterCount)
  843. {
  844. //IDS_DNS_12928 " ERROR: mismatch between adapter count from cache and registry\n"
  845. PrintMessage(pParams, IDS_DNS_12928);
  846. PrintCacheAdapterInfo(pRpcAdapterInfo);
  847. PrintRegistryAdapterInfo(pNetworkInfo);
  848. return;
  849. }
  850. pCurrentCache = pRpcAdapterInfo;
  851. iCurrentAdapter = 0;
  852. while(pCurrentCache && (iCurrentAdapter < pNetworkInfo->AdapterCount))
  853. {
  854. // check DNS domain name
  855. pCurrentRegistry = pNetworkInfo->AdapterArray[iCurrentAdapter];
  856. if((pCurrentCache->pszAdapterDomainName && !pCurrentRegistry->pszAdapterDomain) ||
  857. (!pCurrentCache->pszAdapterDomainName && pCurrentRegistry->pszAdapterDomain) ||
  858. (pCurrentCache->pszAdapterDomainName && pCurrentRegistry->pszAdapterDomain &&
  859. _stricmp(pCurrentCache->pszAdapterDomainName, pCurrentRegistry->pszAdapterDomain)))
  860. {
  861. cacheOk = FALSE;
  862. //IDS_DNS_12929 " ERROR: mismatch between cache and registry info on adapter %s\n"
  863. PrintMessage(pParams, IDS_DNS_12929, pCurrentRegistry->pszAdapterGuidName);
  864. //IDS_DNS_12930 " DNS Domain Name in cache: %s\n"
  865. PrintMessage(pParams, IDS_DNS_12930, pCurrentCache->pszAdapterDomainName);
  866. //IDS_DNS_12931 " DNS Domain Name in registry: %s\n"
  867. PrintMessage(pParams, IDS_DNS_12931, pCurrentRegistry->pszAdapterDomain);
  868. }
  869. // check DNS server list
  870. sameServers = TRUE;
  871. pRpcServer = pCurrentCache->pServerInfo;
  872. count = 0;
  873. while(pRpcServer)
  874. {
  875. count++;
  876. serverFound = FALSE;
  877. for (iServer = 0; iServer < pCurrentRegistry->ServerCount; iServer++)
  878. if(pRpcServer->ipAddress == (pCurrentRegistry->aipServers[iServer]).ipAddress)
  879. serverFound = TRUE;
  880. if(!serverFound)
  881. sameServers = FALSE;
  882. pRpcServer = pRpcServer->pNext;
  883. }
  884. if (count != pCurrentRegistry->ServerCount)
  885. sameServers = FALSE;
  886. if(!sameServers)
  887. {
  888. cacheOk = FALSE;
  889. //IDS_DNS_12932 " ERROR: mismatch between cache and registry info on adapter %s\n"
  890. PrintMessage(pParams, IDS_DNS_12932, pCurrentRegistry->pszAdapterGuidName);
  891. //IDS_DNS_12933 " DNS server list in cache: "
  892. PrintMessage(pParams, IDS_DNS_12933);
  893. for( pRpcServer = pCurrentCache->pServerInfo; pRpcServer; pRpcServer = pRpcServer->pNext)
  894. //IDS_DNS_12934 "%s "
  895. PrintMessage(pParams, IDS_DNS_12934, IP_STRING(pRpcServer->ipAddress));
  896. //IDS_DNS_12935 "\n DNS server list in registry: "
  897. PrintMessage(pParams, IDS_DNS_12935);
  898. for (iServer = 0; iServer < pCurrentRegistry->ServerCount; iServer++)
  899. //IDS_DNS_12936 "%s "
  900. PrintMessage(pParams, IDS_DNS_12936, IP_STRING((pCurrentRegistry->aipServers[iServer]).ipAddress));
  901. //IDS_DNS_12937 "\n"
  902. PrintMessage(pParams, IDS_DNS_12937);
  903. }
  904. pCurrentCache = pCurrentCache->pNext;
  905. iCurrentAdapter++;
  906. }
  907. if (cacheOk)
  908. //IDS_DNS_12938 " NO_ERROR\n"
  909. PrintMessage(pParams, IDS_DNS_12938);
  910. }
  911. */
  912. DNS_STATUS
  913. DnsQueryAndCompare(
  914. IN LPSTR pszName,
  915. IN WORD wType,
  916. IN DWORD fOptions,
  917. IN PIP4_ARRAY aipServers OPTIONAL,
  918. IN OUT PDNS_RECORD * ppQueryResultsSet OPTIONAL,
  919. IN OUT PVOID * pResponseMsg OPTIONAL,
  920. IN PDNS_RECORD pExpected OPTIONAL,
  921. IN BOOL bInclusionOk,
  922. IN BOOL bUnicode,
  923. IN OUT PDNS_RECORD * ppDiff1 OPTIONAL,
  924. IN OUT PDNS_RECORD * ppDiff2 OPTIONAL
  925. )
  926. {
  927. BOOL bCompare = FALSE;
  928. DNS_STATUS status;
  929. DNS_RRSET rrset;
  930. PDNS_RECORD pDnsRecord = NULL;
  931. PDNS_RECORD pAnswers = NULL;
  932. PDNS_RECORD pAdditional = NULL;
  933. PDNS_RECORD pLastAnswer = NULL;
  934. BOOL bIsLocal = FALSE;
  935. DNSDBG( TRACE, (
  936. "\nNETDIAG: DnsQueryAndCompare( %s, type=%d, %08x, serv==%p )\n\n",
  937. pszName,
  938. wType,
  939. fOptions,
  940. aipServers ));
  941. //
  942. // Run the query and get the result
  943. //
  944. if ( fOptions | DNS_QUERY_DATABASE )
  945. {
  946. if (!aipServers || !aipServers->AddrCount)
  947. {
  948. return ERROR_INVALID_PARAMETER;
  949. }
  950. status = QueryDnsServerDatabase(
  951. pszName,
  952. wType,
  953. aipServers->AddrArray[0],
  954. ppQueryResultsSet,
  955. bUnicode,
  956. &bIsLocal );
  957. }
  958. else
  959. {
  960. if ( !bUnicode )
  961. {
  962. status = DnsQuery_UTF8(
  963. pszName,
  964. wType,
  965. fOptions,
  966. aipServers,
  967. ppQueryResultsSet,
  968. pResponseMsg );
  969. }
  970. else // Unicode call
  971. {
  972. status = DnsQuery_W(
  973. (LPWSTR)pszName,
  974. wType,
  975. fOptions,
  976. aipServers,
  977. ppQueryResultsSet,
  978. pResponseMsg);
  979. }
  980. }
  981. if ( pExpected && !status ) //succeed, compare the result
  982. {
  983. // no need to compare if wanted reponse from database and result is from outside
  984. if ( (fOptions | DNS_QUERY_DATABASE) && !bIsLocal )
  985. {
  986. return DNS_INFO_NO_RECORDS;
  987. }
  988. pDnsRecord = *ppQueryResultsSet;
  989. //
  990. // Truncate temporary the record set to answers only
  991. //
  992. if ((pDnsRecord == NULL) || (pDnsRecord->Flags.S.Section > DNSREC_ANSWER))
  993. {
  994. pAnswers = NULL;
  995. pAdditional = pDnsRecord;
  996. }
  997. else
  998. {
  999. pAnswers = pDnsRecord;
  1000. pAdditional = pDnsRecord;
  1001. while (pAdditional->pNext && pAdditional->pNext->Flags.S.Section == DNSREC_ANSWER)
  1002. pAdditional = pAdditional->pNext;
  1003. if(pAdditional->pNext)
  1004. {
  1005. pLastAnswer = pAdditional;
  1006. pAdditional = pAdditional->pNext;
  1007. pLastAnswer->pNext = NULL;
  1008. }
  1009. else
  1010. pAdditional = NULL;
  1011. }
  1012. //
  1013. // Compare the answer with what's expected
  1014. //
  1015. status = DnsRecordSetCompare(
  1016. pAnswers,
  1017. pExpected,
  1018. ppDiff1,
  1019. ppDiff2);
  1020. //
  1021. // Restore the list
  1022. //
  1023. if (pAnswers && pAdditional)
  1024. {
  1025. pLastAnswer->pNext = pAdditional;
  1026. }
  1027. //
  1028. // check if inclusion acceptable
  1029. //
  1030. if (status == TRUE)
  1031. status = NO_ERROR;
  1032. else
  1033. if (bInclusionOk && (ppDiff2 == NULL))
  1034. status = NO_ERROR;
  1035. else
  1036. status = ERROR_NO_MATCH;
  1037. }
  1038. return( status );
  1039. }
  1040. DNS_STATUS
  1041. QueryDnsServerDatabase(
  1042. IN LPSTR pszName,
  1043. IN WORD wType,
  1044. IN IP4_ADDRESS ServerIp,
  1045. OUT PDNS_RECORD * ppDnsRecord,
  1046. IN BOOL bUnicode,
  1047. OUT BOOL * pIsLocal
  1048. )
  1049. {
  1050. PDNS_RECORD pDnsRecord1 = NULL;
  1051. PDNS_RECORD pDnsRecord2 = NULL;
  1052. PDNS_RECORD pdiff1 = NULL;
  1053. PDNS_RECORD pdiff2 = NULL;
  1054. DNS_STATUS status1;
  1055. DNS_STATUS status2;
  1056. DNS_STATUS ret = NO_ERROR;
  1057. PIP4_ARRAY pipServer = NULL;
  1058. BOOL bMatch = FALSE;
  1059. DWORD dwTtl1;
  1060. DWORD dwTtl2;
  1061. DNSDBG( TRACE, (
  1062. "\nNETDIAG: QueryDnsServerDatabase( %s%S, type=%d, %s )\n\n",
  1063. bUnicode ? "" : pszName,
  1064. bUnicode ? (PWSTR)pszName : L"",
  1065. wType,
  1066. IP4_STRING( ServerIp ) ));
  1067. //
  1068. // init results \ validate
  1069. //
  1070. *pIsLocal = FALSE;
  1071. *ppDnsRecord = NULL;
  1072. if ( ServerIp == INADDR_NONE )
  1073. {
  1074. return( ERROR_INVALID_PARAMETER );
  1075. }
  1076. pipServer = Dns_CreateIpArray( 1 );
  1077. if ( ! pipServer )
  1078. {
  1079. return ERROR_OUTOFMEMORY;
  1080. }
  1081. pipServer->AddrArray[0] = ServerIp;
  1082. status1 = DnsQuery_UTF8(
  1083. pszName,
  1084. wType,
  1085. DNS_QUERY_BYPASS_CACHE,
  1086. pipServer,
  1087. &pDnsRecord1,
  1088. NULL
  1089. );
  1090. if (status1 != NO_ERROR)
  1091. status2 = status1;
  1092. else
  1093. {
  1094. Sleep(1500);
  1095. status2 = DnsQuery_UTF8(
  1096. pszName,
  1097. wType,
  1098. DNS_QUERY_BYPASS_CACHE,
  1099. pipServer,
  1100. &pDnsRecord2,
  1101. NULL
  1102. );
  1103. }
  1104. if ((status1 == ERROR_TIMEOUT) || (status2 == ERROR_TIMEOUT))
  1105. {
  1106. ret = ERROR_TIMEOUT;
  1107. goto Cleanup;
  1108. }
  1109. if ((status1 != NO_ERROR) || (status2 != NO_ERROR))
  1110. {
  1111. ret = (status1 != NO_ERROR)?status1:status2;
  1112. goto Cleanup;
  1113. }
  1114. bMatch = DnsRecordSetCompare(
  1115. pDnsRecord1,
  1116. pDnsRecord2,
  1117. &pdiff1,
  1118. &pdiff2
  1119. );
  1120. if (!bMatch)
  1121. {
  1122. ret = DNS_ERROR_TRY_AGAIN_LATER;
  1123. goto Cleanup;
  1124. }
  1125. if (GetAnswerTtl( pDnsRecord1, &dwTtl1 ) && GetAnswerTtl( pDnsRecord2, &dwTtl2 ))
  1126. if ( dwTtl1 != dwTtl2 )
  1127. {
  1128. ret = NO_ERROR;
  1129. *pIsLocal = FALSE;
  1130. }
  1131. else
  1132. {
  1133. ret = NO_ERROR;
  1134. *pIsLocal = TRUE;
  1135. }
  1136. else
  1137. ret = DNS_INFO_NO_RECORDS;
  1138. Cleanup:
  1139. Dns_Free( pipServer );
  1140. if (pdiff1)
  1141. DnsRecordListFree( pdiff1, TRUE );
  1142. if (pdiff2)
  1143. DnsRecordListFree( pdiff2, TRUE );
  1144. if (pDnsRecord1)
  1145. DnsRecordListFree( pDnsRecord1, TRUE );
  1146. if (pDnsRecord2 && (ret != NO_ERROR))
  1147. DnsRecordListFree( pDnsRecord2, TRUE );
  1148. if (ret == NO_ERROR)
  1149. *ppDnsRecord = pDnsRecord2;
  1150. else
  1151. *ppDnsRecord = NULL;
  1152. return ret;
  1153. }
  1154. BOOL
  1155. GetAnswerTtl(
  1156. IN PDNS_RECORD pRec,
  1157. OUT PDWORD pTtl
  1158. )
  1159. {
  1160. PDNS_RECORD pDnsRecord = NULL;
  1161. BOOL bGotAnswer = FALSE;
  1162. *pTtl = 0;
  1163. //
  1164. // Look for answer section
  1165. //
  1166. for (pDnsRecord = pRec; !bGotAnswer && pDnsRecord; pDnsRecord = pDnsRecord->pNext)
  1167. {
  1168. if (pDnsRecord->Flags.S.Section == DNSREC_ANSWER)
  1169. {
  1170. bGotAnswer = TRUE;
  1171. *pTtl = pDnsRecord->dwTtl;
  1172. }
  1173. }
  1174. return bGotAnswer;
  1175. }
  1176. // Get A records from additional section and build a PIP4_ARRAY
  1177. PIP4_ARRAY
  1178. GrabNameServersIp(
  1179. IN PDNS_RECORD pDnsRecord
  1180. )
  1181. {
  1182. DWORD i = 0;
  1183. PDNS_RECORD pCurrent = pDnsRecord;
  1184. PIP4_ARRAY pIpArray = NULL;
  1185. // count records
  1186. while (pCurrent)
  1187. {
  1188. if((pCurrent->wType == DNS_TYPE_A) &&
  1189. (pCurrent->Flags.S.Section == DNSREC_ADDITIONAL))
  1190. i++;
  1191. pCurrent = pCurrent->pNext;
  1192. }
  1193. if (!i)
  1194. return NULL;
  1195. // allocate PIP4_ARRAY
  1196. pIpArray = LocalAlloc(LMEM_FIXED, IP4_ARRAY_SIZE(i));
  1197. if (!pIpArray)
  1198. return NULL;
  1199. // fill PIP4_ARRAY
  1200. pIpArray->AddrCount = i;
  1201. pCurrent = pDnsRecord;
  1202. i=0;
  1203. while (pCurrent)
  1204. {
  1205. if((pCurrent->wType == DNS_TYPE_A) && (pCurrent->Flags.S.Section == DNSREC_ADDITIONAL))
  1206. (pIpArray->AddrArray)[i++] = pCurrent->Data.A.IpAddress;
  1207. pCurrent = pCurrent->pNext;
  1208. }
  1209. return pIpArray;
  1210. }
  1211. DNS_STATUS
  1212. DnsUpdateAllowedTest_W(
  1213. IN HANDLE hContextHandle OPTIONAL,
  1214. IN PWSTR pwszName,
  1215. IN PWSTR pwszAuthZone,
  1216. IN PIP4_ARRAY pAuthDnsServers
  1217. )
  1218. {
  1219. PDNS_RECORD pResult = NULL;
  1220. DNS_STATUS status;
  1221. BOOL bAnyAllowed = FALSE;
  1222. BOOL bAllTimeout = TRUE;
  1223. DWORD i;
  1224. DNSDBG( TRACE, (
  1225. "\nNETDIAG: DnsUpdateAllowedTest_W()\n"
  1226. "\thand = %p\n"
  1227. "\tname = %S\n"
  1228. "\tzone = %S\n"
  1229. "\tservers = %p\n",
  1230. hContextHandle,
  1231. pwszName,
  1232. pwszAuthZone,
  1233. pAuthDnsServers ));
  1234. //
  1235. // Check arguments
  1236. //
  1237. if (!pwszName || !pwszAuthZone || !pAuthDnsServers || !pAuthDnsServers->AddrCount)
  1238. return ERROR_INVALID_PARAMETER;
  1239. //
  1240. // go through server list
  1241. //
  1242. for(i=0; i<pAuthDnsServers->AddrCount; i++)
  1243. {
  1244. //
  1245. // verify if server is a primary
  1246. //
  1247. status = IsDnsServerPrimaryForZone_W(
  1248. pAuthDnsServers->AddrArray[i],
  1249. pwszAuthZone);
  1250. switch(status)
  1251. {
  1252. case ERROR_TIMEOUT:
  1253. case DNS_ERROR_RCODE:
  1254. //
  1255. // it's ok to go check the next server; this one timeouted or it's a secondary
  1256. //
  1257. break;
  1258. case NO_ERROR: // server is a primary
  1259. //
  1260. // Check if update allowed
  1261. //
  1262. status = DnsUpdateTest_W(
  1263. hContextHandle,
  1264. pwszName,
  1265. 0,
  1266. pAuthDnsServers);
  1267. switch(status)
  1268. {
  1269. case ERROR_TIMEOUT:
  1270. break;
  1271. case NO_ERROR:
  1272. case DNS_ERROR_RCODE_YXDOMAIN:
  1273. return NO_ERROR;
  1274. break;
  1275. case DNS_ERROR_RCODE_REFUSED:
  1276. default:
  1277. return status;
  1278. break;
  1279. }
  1280. break;
  1281. default:
  1282. return status;
  1283. break;
  1284. }
  1285. }
  1286. return ERROR_TIMEOUT;
  1287. }
  1288. DNS_STATUS
  1289. DnsUpdateAllowedTest_UTF8(
  1290. IN HANDLE hContextHandle OPTIONAL,
  1291. IN PSTR pszName,
  1292. IN PSTR pszAuthZone,
  1293. IN PIP4_ARRAY pAuthDnsServers
  1294. )
  1295. {
  1296. PDNS_RECORD pResult = NULL;
  1297. DNS_STATUS status;
  1298. BOOL bAnyAllowed = FALSE;
  1299. BOOL bAllTimeout = TRUE;
  1300. DWORD i;
  1301. DNSDBG( TRACE, (
  1302. "\nNETDIAG: DnsUpdateAllowedTest_UTF8()\n"
  1303. "\thand = %p\n"
  1304. "\tname = %s\n"
  1305. "\tzone = %s\n"
  1306. "\tservers = %p\n",
  1307. hContextHandle,
  1308. pszName,
  1309. pszAuthZone,
  1310. pAuthDnsServers ));
  1311. //
  1312. // Check arguments
  1313. //
  1314. if (!pszName || !pszAuthZone || !pAuthDnsServers || !pAuthDnsServers->AddrCount)
  1315. return ERROR_INVALID_PARAMETER;
  1316. //
  1317. // go through server list
  1318. //
  1319. for(i=0; i<pAuthDnsServers->AddrCount; i++)
  1320. {
  1321. //
  1322. // verify if server is a primary
  1323. //
  1324. status = IsDnsServerPrimaryForZone_UTF8(
  1325. pAuthDnsServers->AddrArray[i],
  1326. pszAuthZone);
  1327. switch(status)
  1328. {
  1329. case ERROR_TIMEOUT:
  1330. case DNS_ERROR_RCODE:
  1331. //
  1332. // it's ok to go check the next server; this one timeouted or it's a secondary
  1333. //
  1334. break;
  1335. case NO_ERROR: // server is a primary
  1336. //
  1337. // Check if update allowed
  1338. //
  1339. status = DnsUpdateTest_UTF8(
  1340. hContextHandle,
  1341. pszName,
  1342. 0,
  1343. pAuthDnsServers);
  1344. switch(status)
  1345. {
  1346. case ERROR_TIMEOUT:
  1347. break;
  1348. case NO_ERROR:
  1349. case DNS_ERROR_RCODE_YXDOMAIN:
  1350. return NO_ERROR;
  1351. break;
  1352. case DNS_ERROR_RCODE_REFUSED:
  1353. default:
  1354. return status;
  1355. break;
  1356. }
  1357. break;
  1358. default:
  1359. return status;
  1360. break;
  1361. }
  1362. }
  1363. return ERROR_TIMEOUT;
  1364. }
  1365. DNS_STATUS
  1366. IsDnsServerPrimaryForZone_UTF8(
  1367. IN IP4_ADDRESS Ip,
  1368. IN PSTR pZone
  1369. )
  1370. {
  1371. PDNS_RECORD pDnsRecord = NULL;
  1372. DNS_STATUS status;
  1373. IP4_ARRAY ipArray;
  1374. PIP4_ARRAY pResult = NULL;
  1375. BOOL bFound = FALSE;
  1376. DWORD i;
  1377. //
  1378. // query for SOA
  1379. //
  1380. ipArray.AddrCount = 1;
  1381. ipArray.AddrArray[0] = Ip;
  1382. status = DnsQuery_UTF8(
  1383. pZone,
  1384. DNS_TYPE_SOA,
  1385. DNS_QUERY_BYPASS_CACHE,
  1386. &ipArray,
  1387. &pDnsRecord,
  1388. NULL);
  1389. if(status == NO_ERROR)
  1390. {
  1391. pResult = GrabNameServersIp(pDnsRecord);
  1392. if (pResult)
  1393. {
  1394. bFound = FALSE;
  1395. for (i=0; i<pResult->AddrCount; i++)
  1396. if(pResult->AddrArray[i] == Ip)
  1397. bFound = TRUE;
  1398. LocalFree(pResult);
  1399. if(bFound)
  1400. return NO_ERROR;
  1401. else
  1402. return DNS_ERROR_RCODE;
  1403. }
  1404. else
  1405. return DNS_ERROR_ZONE_CONFIGURATION_ERROR;
  1406. }
  1407. else
  1408. return status;
  1409. }
  1410. DNS_STATUS
  1411. IsDnsServerPrimaryForZone_W(
  1412. IN IP4_ADDRESS Ip,
  1413. IN PWSTR pZone
  1414. )
  1415. {
  1416. PDNS_RECORD pDnsRecord = NULL;
  1417. DNS_STATUS status;
  1418. IP4_ARRAY ipArray;
  1419. PIP4_ARRAY pResult = NULL;
  1420. BOOL bFound = FALSE;
  1421. DWORD i;
  1422. //
  1423. // query for SOA
  1424. //
  1425. ipArray.AddrCount = 1;
  1426. ipArray.AddrArray[0] = Ip;
  1427. status = DnsQuery_W(
  1428. pZone,
  1429. DNS_TYPE_SOA,
  1430. DNS_QUERY_BYPASS_CACHE,
  1431. &ipArray,
  1432. &pDnsRecord,
  1433. NULL);
  1434. if( status == NO_ERROR )
  1435. {
  1436. pResult = GrabNameServersIp(pDnsRecord);
  1437. if (pResult)
  1438. {
  1439. bFound = FALSE;
  1440. for (i=0; i<pResult->AddrCount; i++)
  1441. {
  1442. if(pResult->AddrArray[i] == Ip)
  1443. bFound = TRUE;
  1444. }
  1445. LocalFree(pResult);
  1446. if(bFound)
  1447. return NO_ERROR;
  1448. else
  1449. return DNS_ERROR_RCODE;
  1450. }
  1451. else
  1452. return DNS_ERROR_ZONE_CONFIGURATION_ERROR;
  1453. }
  1454. else
  1455. return status;
  1456. }
  1457. DNS_STATUS
  1458. GetAllDnsServersFromRegistry(
  1459. IN PDNS_NETINFO pNetworkInfo,
  1460. OUT PIP4_ARRAY * ppIpArray
  1461. )
  1462. {
  1463. DNS_STATUS status = NO_ERROR;
  1464. DWORD i;
  1465. DWORD j;
  1466. DWORD idx;
  1467. DWORD idx1;
  1468. DWORD count = 0;
  1469. DWORD dwIP;
  1470. BOOL bFound = FALSE;
  1471. PIP_ARRAY parray = NULL;
  1472. DNSDBG( TRACE, (
  1473. "\nNETDIAG: GetAllDnsServersFromRegistry()\n"
  1474. "\tnetinfo = %p\n"
  1475. "\tpparray = %p\n",
  1476. pNetworkInfo,
  1477. ppIpArray ));
  1478. //
  1479. // DCR: eliminate this routine
  1480. // we already have network info->IP4 routine in dnsapi.dll
  1481. //
  1482. *ppIpArray = NULL;
  1483. if (!pNetworkInfo)
  1484. {
  1485. //
  1486. // Get the DNS Network Information
  1487. // Force rediscovery
  1488. //
  1489. pNetworkInfo = DnsQueryConfigAlloc(
  1490. DnsConfigNetworkInfoUTF8,
  1491. NULL );
  1492. if (!pNetworkInfo)
  1493. {
  1494. status = GetLastError();
  1495. return status;
  1496. }
  1497. }
  1498. for (idx = 0; idx < pNetworkInfo->AdapterCount; idx++)
  1499. {
  1500. count += pNetworkInfo->AdapterArray[idx]->ServerCount;
  1501. }
  1502. if( count == 0 )
  1503. {
  1504. return DNS_ERROR_INVALID_DATA;
  1505. }
  1506. parray = LocalAlloc(LPTR, sizeof(DWORD) + count*sizeof(IP_ADDRESS));
  1507. if ( !parray )
  1508. {
  1509. return GetLastError();
  1510. }
  1511. i = 0;
  1512. for (idx = 0; idx < pNetworkInfo->AdapterCount; idx++)
  1513. {
  1514. PDNS_ADAPTER padapter = pNetworkInfo->AdapterArray[idx];
  1515. for (idx1 = 0; idx1 < padapter->ServerCount; idx1++)
  1516. {
  1517. dwIP = padapter->ServerArray[idx1].IpAddress;
  1518. bFound = FALSE;
  1519. if ( i>0 )
  1520. {
  1521. for (j = 0; j < i; j++)
  1522. {
  1523. if(dwIP == parray->AddrArray[j])
  1524. bFound = TRUE;
  1525. }
  1526. }
  1527. if (!bFound)
  1528. parray->AddrArray[i++] = dwIP;
  1529. }
  1530. }
  1531. parray->AddrCount = i;
  1532. *ppIpArray = parray;
  1533. return DNS_ERROR_RCODE_NO_ERROR;
  1534. }
  1535. //
  1536. // End dnscmn.c
  1537. //