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.

1553 lines
53 KiB

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