From c2aae726ea3f697c50f8d2304e2a9e69c56ab90f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 17 Nov 2006 21:46:26 +0000 Subject: r19762: libaddns/*[ch] code fixes donated by Centeris Corporation (http://www.centeris.com/) under my copyright. * Rework error reporting to use DNS_ERROR instead of int32 * Convert memory allocation to use talloc() * Generalize the DNS request/response packet marshalling * Fix the secure update requests (This used to be commit c78798333616c3f823514df0f58da2eb3a30a988) --- source3/libaddns/dnsutils.c | 600 ++++++-------------------------------------- 1 file changed, 77 insertions(+), 523 deletions(-) (limited to 'source3/libaddns/dnsutils.c') diff --git a/source3/libaddns/dnsutils.c b/source3/libaddns/dnsutils.c index 6621509cc5..5f0ab04219 100644 --- a/source3/libaddns/dnsutils.c +++ b/source3/libaddns/dnsutils.c @@ -27,573 +27,127 @@ #include "dns.h" #include -#define TRUE 1 -#define FALSE 0 - -#define STATE_BEGIN 0 -#define STATE_LABEL 1 -#define STATE_FINISH 2 - -#define TOKEN_LABEL 1 -#define TOKEN_SEPARATOR 2 -#define TOKEN_EOS 3 - -/********************************************************************* -*********************************************************************/ - -static int32 getToken( const char *pszString, char *pszToken, int32 * pdwToken, - int32 * pdwPosition ) -{ - int32 dwError = 0; - char c = 0; - int32 dwToken = 0; - int32 i = 0; - int32 dwState = 0; - int32 dwPosition = 0; - - dwPosition = *pdwPosition; - dwState = STATE_BEGIN; - while ( dwState != STATE_FINISH ) { - c = pszString[dwPosition]; - if ( c == '\0' ) { - if ( dwState == STATE_LABEL ) { - dwToken = TOKEN_LABEL; - dwState = STATE_FINISH; - continue; - } else if ( dwState == STATE_BEGIN ) { - dwToken = TOKEN_EOS; - dwState = STATE_FINISH; - continue; - } - } else if ( isalnum( c ) || c == '-' ) { - pszToken[i++] = c; - dwPosition++; - dwState = STATE_LABEL; - continue; - } else if ( c == '.' ) { - if ( dwState == STATE_LABEL ) { - dwToken = TOKEN_LABEL; - dwState = STATE_FINISH; - continue; - } else if ( dwState == STATE_BEGIN ) { - dwToken = TOKEN_SEPARATOR; - dwPosition++; - dwState = STATE_FINISH; - continue; - } - } else { - if ( dwState == STATE_LABEL ) { - dwToken = TOKEN_LABEL; - dwState = STATE_FINISH; - } else if ( dwState == 0 ) { - dwError = ERROR_INVALID_PARAMETER; - dwState = STATE_FINISH; - } - } - } - *pdwPosition = dwPosition; - *pdwToken = dwToken; - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSMakeLabel( char *szLabel, DNS_DOMAIN_LABEL ** ppLabel ) -{ - DNS_DOMAIN_LABEL *pLabel = NULL; - char *pszLabel = NULL; - int32 dwError = 0; - - dwError = - DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ), - ( void * ) &pLabel ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSAllocateString( szLabel, &pszLabel ); - BAIL_ON_ERROR( dwError ); - - pLabel->pszLabel = pszLabel; - pLabel->dwLength = ( int32 ) strlen( pszLabel ); - *ppLabel = pLabel; - return dwError; - - error: - - if ( pLabel ) { - DNSFreeMemory( pLabel ); - } - *ppLabel = NULL; - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static void DNSFreeLabel( DNS_DOMAIN_LABEL * pLabel ) +static DNS_ERROR LabelList( TALLOC_CTX *mem_ctx, + const char *name, + struct dns_domain_label **presult ) { - if ( pLabel ) { - DNSFreeMemory( pLabel ); - } - return; -} + struct dns_domain_label *result; + const char *dot; -/********************************************************************* -*********************************************************************/ + for (dot = name; *dot != '\0'; dot += 1) { + char c = *dot; -void DNSFreeLabelList(DNS_DOMAIN_LABEL *pLabelList) -{ - DNS_DOMAIN_LABEL *pTemp = NULL; - while(pLabelList) { - pTemp = pLabelList; - pLabelList = pLabelList->pNext; - DNSFreeLabel(pTemp); - } - - return; -} - -/********************************************************************* -*********************************************************************/ - -void DNSFreeDomainName(DNS_DOMAIN_NAME *pDomainName) -{ - DNSFreeLabelList(pDomainName->pLabelList); - DNSFreeMemory(pDomainName); - - return; -} + if (c == '.') + break; -/********************************************************************* -*********************************************************************/ + if (c == '-') continue; + if ((c >= 'a') && (c <= 'z')) continue; + if ((c >= 'A') && (c <= 'Z')) continue; + if ((c >= '0') && (c <= '9')) continue; -static int32 LabelList( const char *pszString, int32 * pdwPosition, DNS_DOMAIN_LABEL ** ppList ) -{ - int32 dwError = 0; - DNS_DOMAIN_LABEL *pList = NULL; - DNS_DOMAIN_LABEL *pLabel = NULL; - int32 dwToken = 0; - char szToken[64]; - - memset( szToken, 0, 64 ); - dwError = getToken( pszString, szToken, &dwToken, pdwPosition ); - BAIL_ON_ERROR( dwError ); - if ( dwToken != TOKEN_LABEL ) { - dwError = ERROR_INVALID_PARAMETER; - BAIL_ON_ERROR( dwError ); + return ERROR_DNS_INVALID_NAME; } - dwError = DNSMakeLabel( szToken, &pLabel ); - BAIL_ON_ERROR( dwError ); - - memset( szToken, 0, 64 ); - dwError = getToken( pszString, szToken, &dwToken, pdwPosition ); - BAIL_ON_ERROR( dwError ); - if ( dwToken == TOKEN_EOS ) { - *ppList = pLabel; - return dwError; - } else if ( dwToken == TOKEN_SEPARATOR ) { - dwError = LabelList( pszString, pdwPosition, &pList ); - BAIL_ON_ERROR( dwError ); - - pLabel->pNext = pList; - *ppList = pLabel; + if ((dot - name) > 63) { + /* + * DNS labels can only be 63 chars long + */ + return ERROR_DNS_INVALID_NAME; } - return dwError; - - error: - if ( pLabel ) { - DNSFreeLabel( pLabel ); + if (!(result = TALLOC_ZERO_P(mem_ctx, struct dns_domain_label))) { + return ERROR_DNS_NO_MEMORY; } - return dwError; -} - -/********************************************************************* -*********************************************************************/ + if (*dot == '\0') { + /* + * No dot around, so this is the last component + */ -static int32 DNSGetDomainNameOffset( uint8 * pBuffer ) -{ - uint8 uLen = 0; - uint8 uLen1; - int32 dwOffset = 0; - - uLen1 = *pBuffer; - if ( uLen1 & 0xC0 ) { - dwOffset += 2; - - } else { - - while ( 1 ) { - - uLen = *pBuffer; - pBuffer++; - dwOffset++; - if ( uLen == 0 ) { - break; - } - dwOffset += uLen; - pBuffer += uLen; + if (!(result->label = talloc_strdup(result, name))) { + TALLOC_FREE(result); + return ERROR_DNS_NO_MEMORY; } + result->len = strlen(result->label); + *presult = result; + return ERROR_DNS_SUCCESS; } - return ( dwOffset ); -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSGenerateIdentifier( int16 * pwIdentifier ) -{ - int32 dwError = 0; - - *pwIdentifier = random( ); - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSGetDomainNameLength( DNS_DOMAIN_NAME * pDomainName, int32 * pdwLength ) -{ - int32 dwError = 0; - int32 dwLength = 0; - DNS_DOMAIN_LABEL *pDomainLabel = NULL; - - if ( !pDomainName ) { - dwError = ERROR_INVALID_PARAMETER; - BAIL_ON_ERROR( dwError ); - } - pDomainLabel = pDomainName->pLabelList; - - while ( pDomainLabel ) { - dwLength += pDomainLabel->dwLength; - dwLength += 1; - pDomainLabel = pDomainLabel->pNext; - } - dwLength += 1; - *pdwLength = dwLength; - - return dwError; - error: - - *pdwLength = 0; - return dwError; -} -/********************************************************************* -*********************************************************************/ - -int32 DNSCopyDomainName( uint8 * pBuffer, - DNS_DOMAIN_NAME * pDomainName, int32 * pdwCopied ) -{ - int32 dwError = 0; - DNS_DOMAIN_LABEL *pDomainLabel = NULL; - uint8 uChar = 0; - int32 dwCopied = 0; - - if ( !pDomainName ) { - dwError = ERROR_INVALID_PARAMETER; - BAIL_ON_ERROR( dwError ); - } + if (dot[1] == '.') { + /* + * Two dots in a row, reject + */ - pDomainLabel = pDomainName->pLabelList; - while ( pDomainLabel ) { - uChar = ( uint8 ) pDomainLabel->dwLength; - memcpy( pBuffer + dwCopied, &uChar, sizeof( uint8 ) ); - dwCopied += sizeof( uint8 ); - memcpy( pBuffer + dwCopied, pDomainLabel->pszLabel, - pDomainLabel->dwLength ); - dwCopied += pDomainLabel->dwLength; - pDomainLabel = pDomainLabel->pNext; + TALLOC_FREE(result); + return ERROR_DNS_INVALID_NAME; } - uChar = 0; - memcpy( pBuffer + dwCopied, &uChar, sizeof( uint8 ) ); - dwCopied += sizeof( uint8 ); - *pdwCopied = dwCopied; - return dwError; + if (dot[1] != '\0') { + /* + * Something follows, get the rest + */ - error: - *pdwCopied = 0; - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSGenerateKeyName( char **ppszKeyName ) -{ - int32 dwError = 0; -#if defined(WITH_DNS_UPDATES) - char *pszKeyName = NULL; - char szTemp[256]; - char szBuffer[256]; - unsigned char uuid[16]; - - memset( szTemp, 0, 256 ); - memset( szBuffer, 0, 256 ); - memset( uuid, 0, 16 ); - - uuid_generate( uuid ); + DNS_ERROR err = LabelList(result, dot+1, &result->next); - uuid_unparse( uuid, szBuffer ); - - strcpy( szTemp, szBuffer ); - dwError = DNSAllocateString( szTemp, &pszKeyName ); - BAIL_ON_ERROR( dwError ); - - *ppszKeyName = pszKeyName; - - return dwError; - - error: -#endif - - *ppszKeyName = NULL; - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSDomainNameFromString( const char *pszDomainName, - DNS_DOMAIN_NAME ** ppDomainName ) -{ - int32 dwError = 0; - int32 dwPosition = 0; - DNS_DOMAIN_NAME *pDomainName = NULL; - DNS_DOMAIN_LABEL *pLabelList = NULL; - - if ( !pszDomainName || !*pszDomainName ) { - dwError = ERROR_INVALID_PARAMETER; - return dwError; + if (!ERR_DNS_IS_OK(err)) { + TALLOC_FREE(result); + return err; + } } - dwError = LabelList( pszDomainName, &dwPosition, &pLabelList ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ), - ( void * ) &pDomainName ); - BAIL_ON_ERROR( dwError ); - - pDomainName->pLabelList = pLabelList; - - *ppDomainName = pDomainName; + result->len = (dot - name); - return dwError; - - error: - - if ( pLabelList ) { - DNSFreeLabelList( pLabelList ); + if (!(result->label = talloc_strndup(result, name, result->len))) { + TALLOC_FREE(result); + return ERROR_DNS_NO_MEMORY; } - *ppDomainName = NULL; - return dwError; + *presult = result; + return ERROR_DNS_SUCCESS; } - -/********************************************************************* -*********************************************************************/ - -int32 DNSAppendLabel( DNS_DOMAIN_LABEL * pLabelList, - DNS_DOMAIN_LABEL * pLabel, - DNS_DOMAIN_LABEL ** ppNewLabelList ) +DNS_ERROR dns_domain_name_from_string( TALLOC_CTX *mem_ctx, + const char *pszDomainName, + struct dns_domain_name **presult ) { - DNS_DOMAIN_LABEL **ppLabelList = NULL; - int32 dwError = 0; + struct dns_domain_name *result; + DNS_ERROR err; - if ( pLabelList == NULL ) { - *ppNewLabelList = pLabel; - return dwError; + if (!(result = talloc(mem_ctx, struct dns_domain_name))) { + return ERROR_DNS_NO_MEMORY; } - ppLabelList = &pLabelList; - - while ( ( *ppLabelList )->pNext ) { - ppLabelList = &( ( *ppLabelList )->pNext ); + err = LabelList( result, pszDomainName, &result->pLabelList ); + if (!ERR_DNS_IS_OK(err)) { + TALLOC_FREE(result); + return err; } - ( *ppLabelList )->pNext = pLabel; - *ppNewLabelList = pLabelList; - return dwError; + *presult = result; + return ERROR_DNS_SUCCESS; } /********************************************************************* *********************************************************************/ -int32 GetLastError( ) +char *dns_generate_keyname( TALLOC_CTX *mem_ctx ) { - return ( errno ); -} - -/********************************************************************* -*********************************************************************/ + char *result = NULL; +#if defined(WITH_DNS_UPDATES) -int32 WSAGetLastError( void ) -{ - return ( errno ); -} + uuid_t uuid; -/********************************************************************* -*********************************************************************/ - -void DNSRecordGenerateOffsets( DNS_RR_RECORD * pDNSRecord ) -{ - int32 dwOffset = 0; - uint8 *pRData = NULL; - int16 wKeySize, wnKeySize = 0; - - pRData = pDNSRecord->pRData; - switch ( pDNSRecord->RRHeader.wType ) { - case QTYPE_TKEY: - pDNSRecord->Offsets.TKey.wAlgorithmOffset = - ( int16 ) dwOffset; - dwOffset += DNSGetDomainNameOffset( pRData ); - pDNSRecord->Offsets.TKey.wInceptionOffset = - ( int16 ) dwOffset; - dwOffset += sizeof( int32 ); - pDNSRecord->Offsets.TKey.wExpirationOffset = - ( int16 ) dwOffset; - dwOffset += sizeof( int32 ); - pDNSRecord->Offsets.TKey.wModeOffset = ( int16 ) dwOffset; - dwOffset += sizeof( int16 ); - pDNSRecord->Offsets.TKey.wErrorOffset = ( int16 ) dwOffset; - dwOffset += sizeof( int16 ); - pDNSRecord->Offsets.TKey.wKeySizeOffset = ( int16 ) dwOffset; - dwOffset += sizeof( int16 ); - pDNSRecord->Offsets.TKey.wKeyDataOffset = ( int16 ) dwOffset; - - memcpy( &wnKeySize, - pRData + pDNSRecord->Offsets.TKey.wKeySizeOffset, - sizeof( int16 ) ); - wKeySize = ntohs( wnKeySize ); - - dwOffset += wKeySize; - pDNSRecord->Offsets.TKey.wOtherSizeOffset = - ( int16 ) dwOffset; - dwOffset += sizeof( int16 ); - pDNSRecord->Offsets.TKey.wOtherDataOffset = - ( int16 ) dwOffset; - break; - - case QTYPE_TSIG: - break; + /* + * uuid_unparse gives 36 bytes plus '\0' + */ + if (!(result = TALLOC_ARRAY(mem_ctx, char, 37))) { + return NULL; } - return; -} - -/********************************************************************* -*********************************************************************/ - -int32 MapDNSResponseCodes( int16 wResponseCode ) -{ - int16 wnResponseCode = 0; - uint8 *pByte = NULL; - wnResponseCode = htons( wResponseCode ); - pByte = ( uint8 * ) & wnResponseCode; + uuid_generate( uuid ); + uuid_unparse( uuid, result ); -#if 0 - printf( "Byte 0 - %.2x\n", pByte[0] ); - printf( "Byte 1 - %.2x\n", pByte[1] ); #endif - /* Bit 3, 2, 1, 0 of Byte 2 represent the RCode */ - return ( ( int32 ) pByte[1] ); + return result; } - -/********************************************************************* -*********************************************************************/ - -int32 DNSAllocateMemory(int32 dwSize, void * _ppMemory) -{ - void **ppMemory = (void **)_ppMemory; - int32 dwError = 0; - void * pMemory = NULL; - - pMemory = malloc(dwSize); - if (!pMemory){ - dwError = ERROR_OUTOFMEMORY; - *ppMemory = NULL; - }else { - memset(pMemory,0, dwSize); - *ppMemory = pMemory; - } - return (dwError); -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSReallocMemory(void * pMemory, void * _ppNewMemory, int32 dwSize) -{ - void **ppNewMemory = (void **)_ppNewMemory; - int32 dwError = 0; - void * pNewMemory = NULL; - - if (pMemory == NULL) { - pNewMemory = malloc(dwSize); - memset(pNewMemory, 0, dwSize); - }else { - pNewMemory = realloc(pMemory, dwSize); - } - if (!pNewMemory){ - dwError = ERROR_OUTOFMEMORY; - *ppNewMemory = NULL; - }else { - *ppNewMemory = pNewMemory; - } - - return(dwError); -} - -/********************************************************************* -*********************************************************************/ - -void DNSFreeMemory( void * pMemory ) -{ - free(pMemory); - return; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSAllocateString(char *pszInputString, char **ppszOutputString) -{ - int32 dwError = 0; - int32 dwLen = 0; - char * pszOutputString = NULL; - - if (!pszInputString || !*pszInputString){ - dwError = ERROR_INVALID_PARAMETER; - BAIL_ON_ERROR(dwError); - } - dwLen = (int32)strlen(pszInputString); - dwError = DNSAllocateMemory(dwLen+1, (void *)&pszOutputString); - BAIL_ON_ERROR(dwError); - - strcpy(pszOutputString, pszInputString); - - *ppszOutputString = pszOutputString; - - return(dwError); -error: - *ppszOutputString = pszOutputString; - return(dwError); -} - -/********************************************************************* -*********************************************************************/ - -void DNSFreeString(char * pszString) -{ - return; -} - - - -- cgit