X-Git-Url: https://git.reactos.org/?p=reactos.git;a=blobdiff_plain;f=reactos%2Flib%2Fdnsapi%2Fdnsapi%2Fquery.c;h=d8b7fae4d487d91cf603f8b6551a19eaac022946;hp=c2f3ddde1acd853c12a406d8d3add604f563e3dc;hb=0c0ecd45ea61f80c7e254aa5ef307ee5ac189ddf;hpb=d42bd99ca1023f9cdbf148314510411a76a37684 diff --git a/reactos/lib/dnsapi/dnsapi/query.c b/reactos/lib/dnsapi/dnsapi/query.c index c2f3ddde1ac..d8b7fae4d48 100644 --- a/reactos/lib/dnsapi/dnsapi/query.c +++ b/reactos/lib/dnsapi/dnsapi/query.c @@ -8,11 +8,10 @@ * 12/15/03 -- Created */ -#include -#include -#include -#include -#include +#include "precomp.h" + +#define NDEBUG +#include /* DnsQuery **************************** * Begin a DNS query, and allow the result to be placed in the application @@ -35,8 +34,10 @@ char *xstrsave(const char *str) { char *p; - p= RtlAllocateHeap( RtlGetProcessHeap(), 0, strlen(str)+1 ); - strcpy(p,str); + p = RtlAllocateHeap( RtlGetProcessHeap(), 0, strlen(str)+1 ); + if ( NULL != p ) { + strcpy(p,str); + } return p; } @@ -45,12 +46,14 @@ DNS_STATUS WINAPI DnsQuery_A WORD Type, DWORD Options, PIP4_ARRAY Servers, - PDNS_RECORDA *QueryResultSet, + PDNS_RECORD *QueryResultSet, PVOID *Reserved ) { adns_state astate; int quflags = 0; int adns_error; adns_answer *answer; + LPSTR CurrentName; + unsigned CNameLoop; *QueryResultSet = 0; @@ -62,33 +65,83 @@ DNS_STATUS WINAPI DnsQuery_A adns_if_noserverwarn, 0 ); if( adns_error != adns_s_ok ) { - adns_finish( astate ); return DnsIntTranslateAdnsToDNS_STATUS( adns_error ); } - adns_error = adns_synchronous( astate, - Name, - adns_r_addr, - quflags, - &answer ); + /* + * adns doesn't resolve chained CNAME records (a CNAME which points to + * another CNAME pointing to another... pointing to an A record), according + * to a mailing list thread the authors believe that chained CNAME records + * are invalid and the DNS entries should be fixed. That's a nice academic + * standpoint, but there certainly are chained CNAME records out there, + * even some fairly major ones (at the time of this writing + * download.mozilla.org is a chained CNAME). Everyone else seems to resolve + * these fine, so we should too. So we loop here to try to resolve CNAME + * chains ourselves. Of course, there must be a limit to protect against + * CNAME loops. + */ + +#define CNAME_LOOP_MAX 16 + + CurrentName = (LPSTR) Name; + for ( CNameLoop = 0; CNameLoop < CNAME_LOOP_MAX; CNameLoop++ ) { + adns_error = adns_synchronous( astate, + CurrentName, + adns_r_addr, + quflags, + &answer ); - if( adns_error != adns_s_ok ) { - adns_finish( astate ); - return DnsIntTranslateAdnsToDNS_STATUS( adns_error ); - } + if( adns_error != adns_s_ok ) { + adns_finish( astate ); + if ( CurrentName != Name ) { + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + } + return DnsIntTranslateAdnsToDNS_STATUS( adns_error ); + } - *QueryResultSet = (PDNS_RECORDA)RtlAllocateHeap( RtlGetProcessHeap(), 0, - sizeof( DNS_RECORDA ) ); - (*QueryResultSet)->wType = Type; - (*QueryResultSet)->pName = xstrsave( Name ); - (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA); - (*QueryResultSet)->Data.A.IpAddress = - answer->rrs.addr->addr.inet.sin_addr.s_addr; + if( answer && answer->rrs.addr ) { + if ( CurrentName != Name ) { + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + } + *QueryResultSet = + (PDNS_RECORD)RtlAllocateHeap( RtlGetProcessHeap(), 0, + sizeof( DNS_RECORD ) ); + if ( NULL == *QueryResultSet ) { + adns_finish( astate ); + return ERROR_OUTOFMEMORY; + } + (*QueryResultSet)->pNext = NULL; + (*QueryResultSet)->wType = Type; + (*QueryResultSet)->wDataLength = sizeof(DNS_A_DATA); + (*QueryResultSet)->Data.A.IpAddress = + answer->rrs.addr->addr.inet.sin_addr.s_addr; + adns_finish( astate ); + (*QueryResultSet)->pName = xstrsave( Name ); + return NULL != (*QueryResultSet)->pName ? ERROR_SUCCESS : + ERROR_OUTOFMEMORY; + } + if ( NULL == answer || adns_s_prohibitedcname != answer->status || + NULL == answer->cname ) { + adns_finish( astate ); + if ( CurrentName != Name ) { + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + } + return ERROR_FILE_NOT_FOUND; + } + if ( CurrentName != Name ) { + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + } + CurrentName = xstrsave( answer->cname ); + if ( NULL == CurrentName ) { + adns_finish( astate ); + return ERROR_OUTOFMEMORY; + } + } adns_finish( astate ); - return ERROR_SUCCESS; - + RtlFreeHeap( CurrentName, 0, GetProcessHeap() ); + return ERROR_FILE_NOT_FOUND; default: - return DNS_ERROR_NO_MEMORY; /* XXX arty: find a better error code. */ + return ERROR_OUTOFMEMORY; /* XXX arty: find a better error code. */ } } @@ -112,13 +165,13 @@ DNS_STATUS WINAPI DnsQuery_W WORD Type, DWORD Options, PIP4_ARRAY Servers, - PDNS_RECORDW *QueryResultSet, + PDNS_RECORD *QueryResultSet, PVOID *Reserved ) { - int i; + UINT i; PCHAR Buffer; DNS_STATUS Status; - PDNS_RECORDA QueryResultWide; - PDNS_RECORDW ConvertedRecord = 0, LastRecord = 0; + PDNS_RECORD QueryResultWide; + PDNS_RECORD ConvertedRecord = 0, LastRecord = 0; Buffer = DnsWToC( Name ); @@ -129,11 +182,13 @@ DNS_STATUS WINAPI DnsQuery_W switch( QueryResultWide->wType ) { case DNS_TYPE_A: case DNS_TYPE_WKS: +#ifndef __USE_W32API case DNS_TYPE_AAAA: case DNS_TYPE_KEY: +#endif ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0, - sizeof(DNS_RECORDA) ); - ConvertedRecord->pName = DnsCToW( QueryResultWide->pName ); + sizeof(DNS_RECORD) ); + ConvertedRecord->pName = (PCHAR)DnsCToW( QueryResultWide->pName ); ConvertedRecord->wType = QueryResultWide->wType; ConvertedRecord->wDataLength = QueryResultWide->wDataLength; memcpy( ConvertedRecord, QueryResultWide, @@ -149,57 +204,63 @@ DNS_STATUS WINAPI DnsQuery_W case DNS_TYPE_MG: case DNS_TYPE_MR: ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0, - sizeof(DNS_RECORDA) ); - ConvertedRecord->pName = DnsCToW( QueryResultWide->pName ); + sizeof(DNS_RECORD) ); + ConvertedRecord->pName = (PCHAR)DnsCToW( QueryResultWide->pName ); ConvertedRecord->wType = QueryResultWide->wType; - ConvertedRecord->wDataLength = sizeof(DNS_PTR_DATAA); + ConvertedRecord->wDataLength = sizeof(DNS_PTR_DATA); ConvertedRecord->Data.PTR.pNameHost = - DnsCToW( QueryResultWide->Data.PTR.pNameHost ); + (PCHAR)DnsCToW( QueryResultWide->Data.PTR.pNameHost ); break; case DNS_TYPE_MINFO: +#ifndef __USE_W32API case DNS_TYPE_RP: +#endif ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0, - sizeof(DNS_RECORDA) ); - ConvertedRecord->pName = DnsCToW( QueryResultWide->pName ); + sizeof(DNS_RECORD) ); + ConvertedRecord->pName = (PCHAR)DnsCToW( QueryResultWide->pName ); ConvertedRecord->wType = QueryResultWide->wType; - ConvertedRecord->wDataLength = sizeof(DNS_MINFO_DATAA); + ConvertedRecord->wDataLength = sizeof(DNS_MINFO_DATA); ConvertedRecord->Data.MINFO.pNameMailbox = - DnsCToW( QueryResultWide->Data.MINFO.pNameMailbox ); + (PCHAR)DnsCToW( QueryResultWide->Data.MINFO.pNameMailbox ); ConvertedRecord->Data.MINFO.pNameErrorsMailbox = - DnsCToW( QueryResultWide->Data.MINFO.pNameErrorsMailbox ); + (PCHAR)DnsCToW( QueryResultWide->Data.MINFO.pNameErrorsMailbox ); break; case DNS_TYPE_MX: +#ifndef __USE_W32API case DNS_TYPE_AFSDB: case DNS_TYPE_RT: +#endif ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0, - sizeof(DNS_RECORDA) ); - ConvertedRecord->pName = DnsCToW( QueryResultWide->pName ); + sizeof(DNS_RECORD) ); + ConvertedRecord->pName = (PCHAR)DnsCToW( QueryResultWide->pName ); ConvertedRecord->wType = QueryResultWide->wType; - ConvertedRecord->wDataLength = sizeof(DNS_MX_DATAW); + ConvertedRecord->wDataLength = sizeof(DNS_MX_DATA); ConvertedRecord->Data.MX.pNameExchange = - DnsCToW( QueryResultWide->Data.MX.pNameExchange ); + (PCHAR)DnsCToW( QueryResultWide->Data.MX.pNameExchange ); ConvertedRecord->Data.MX.wPreference = - QueryResultWide->Data.MX.wPreference; + QueryResultWide->Data.MX.wPreference; break; +#ifndef __USE_W32API case DNS_TYPE_TXT: - case DNS_TYPE_HINFO: case DNS_TYPE_ISDN: +#endif + case DNS_TYPE_HINFO: ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0, - sizeof(DNS_TXT_DATAW) + + sizeof(DNS_TXT_DATA) + QueryResultWide-> Data.TXT.dwStringCount ); - ConvertedRecord->pName = DnsCToW( QueryResultWide->pName ); + ConvertedRecord->pName = (PCHAR)DnsCToW( QueryResultWide->pName ); ConvertedRecord->wType = QueryResultWide->wType; ConvertedRecord->wDataLength = - sizeof(DNS_TXT_DATAW) + + sizeof(DNS_TXT_DATA) + (sizeof(PWCHAR) * QueryResultWide->Data.TXT.dwStringCount); ConvertedRecord->Data.TXT.dwStringCount = QueryResultWide->Data.TXT.dwStringCount; for( i = 0; i < ConvertedRecord->Data.TXT.dwStringCount; i++ ) { ConvertedRecord->Data.TXT.pStringArray[i] = - DnsCToW( QueryResultWide->Data.TXT.pStringArray[i] ); + (PCHAR)DnsCToW( QueryResultWide->Data.TXT.pStringArray[i] ); } break; @@ -208,7 +269,7 @@ DNS_STATUS WINAPI DnsQuery_W sizeof(DNS_NULL_DATA) + QueryResultWide-> Data.Null.dwByteCount ); - ConvertedRecord->pName = DnsCToW( QueryResultWide->pName ); + ConvertedRecord->pName = (PCHAR)DnsCToW( QueryResultWide->pName ); ConvertedRecord->wType = QueryResultWide->wType; ConvertedRecord->wDataLength = sizeof(DNS_NULL_DATA) + QueryResultWide->Data.Null.dwByteCount; @@ -219,6 +280,7 @@ DNS_STATUS WINAPI DnsQuery_W QueryResultWide->Data.Null.dwByteCount ); break; +#ifndef __USE_W32API case DNS_TYPE_SIG: ConvertedRecord = RtlAllocateHeap( RtlGetProcessHeap(), 0, sizeof(DNS_RECORDA) ); @@ -257,6 +319,7 @@ DNS_STATUS WINAPI DnsQuery_W ConvertedRecord->Data.SRV.pNameTarget = DnsCToW( QueryResultWide->Data.SRV.pNameTarget ); break; +#endif } if( LastRecord ) { @@ -280,69 +343,75 @@ DNS_STATUS WINAPI DnsQuery_UTF8 WORD Type, DWORD Options, PIP4_ARRAY Servers, - PDNS_RECORDA *QueryResultSet, + PDNS_RECORD *QueryResultSet, PVOID *Reserved ) { return DnsQuery_UTF8( Name, Type, Options, Servers, QueryResultSet, Reserved ); } -void DnsIntFreeRecordList( PDNS_RECORDA ToDelete ) { - int i; - PDNS_RECORDA next = 0; +void DnsIntFreeRecordList( PDNS_RECORD ToDelete ) { + UINT i; + PDNS_RECORD next = 0; while( ToDelete ) { - if( ToDelete->pName ) - RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->pName ); - switch( ToDelete->wType ) { - case DNS_TYPE_CNAME: - case DNS_TYPE_PTR: - case DNS_TYPE_NS: - case DNS_TYPE_MB: - case DNS_TYPE_MD: - case DNS_TYPE_MF: - case DNS_TYPE_MG: - case DNS_TYPE_MR: - RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.PTR.pNameHost ); - break; - case DNS_TYPE_MINFO: - case DNS_TYPE_RP: - RtlFreeHeap( RtlGetProcessHeap(), 0, - ToDelete->Data.MINFO.pNameMailbox ); - RtlFreeHeap( RtlGetProcessHeap(), 0, - ToDelete->Data.MINFO.pNameErrorsMailbox ); - break; - - case DNS_TYPE_MX: - case DNS_TYPE_AFSDB: - case DNS_TYPE_RT: - RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.MX.pNameExchange ); - break; - - case DNS_TYPE_TXT: - case DNS_TYPE_HINFO: - case DNS_TYPE_ISDN: - for( i = 0; i < ToDelete->Data.TXT.dwStringCount; i++ ) { - RtlFreeHeap( RtlGetProcessHeap(), 0, - ToDelete->Data.TXT.pStringArray[i] ); + if( ToDelete->pName ) + RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->pName ); + switch( ToDelete->wType ) { + case DNS_TYPE_CNAME: + case DNS_TYPE_PTR: + case DNS_TYPE_NS: + case DNS_TYPE_MB: + case DNS_TYPE_MD: + case DNS_TYPE_MF: + case DNS_TYPE_MG: + case DNS_TYPE_MR: + RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.PTR.pNameHost ); + break; + case DNS_TYPE_MINFO: +#ifndef __USE_W32API + case DNS_TYPE_RP: + RtlFreeHeap( RtlGetProcessHeap(), 0, + ToDelete->Data.MINFO.pNameMailbox ); + RtlFreeHeap( RtlGetProcessHeap(), 0, + ToDelete->Data.MINFO.pNameErrorsMailbox ); + break; + + case DNS_TYPE_AFSDB: + case DNS_TYPE_RT: +#endif + case DNS_TYPE_MX: + RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.MX.pNameExchange ); + break; + +#ifndef __USE_W32API + case DNS_TYPE_TXT: + case DNS_TYPE_ISDN: +#endif + case DNS_TYPE_HINFO: + for( i = 0; i < ToDelete->Data.TXT.dwStringCount; i++ ) { + RtlFreeHeap( RtlGetProcessHeap(), 0, + ToDelete->Data.TXT.pStringArray[i] ); + } + RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.TXT.pStringArray ); + break; + +#ifndef __USE_W32API + case DNS_TYPE_SIG: + RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.SIG.pNameSigner ); + break; + + case DNS_TYPE_NXT: + RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.NXT.pNameNext ); + break; + + case DNS_TYPE_SRV: + RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.SRV.pNameTarget ); + break; +#endif } - RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.TXT.pStringArray ); - break; - - case DNS_TYPE_SIG: - RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.SIG.pNameSigner ); - break; - - case DNS_TYPE_NXT: - RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.NXT.pNameNext ); - break; - - case DNS_TYPE_SRV: - RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete->Data.SRV.pNameTarget ); - break; - } - - next = ToDelete->pNext; - RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete ); - ToDelete = next; + + next = ToDelete->pNext; + RtlFreeHeap( RtlGetProcessHeap(), 0, ToDelete ); + ToDelete = next; } }