summaryrefslogtreecommitdiff
path: root/source3/libaddns/dnsrecord.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-08-24 15:43:32 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:38:48 -0500
commit5693e6c599a586b1bb19eea375c6b1e22526031c (patch)
tree9190fcd83791a892aaca33debd400fd0b4124fc2 /source3/libaddns/dnsrecord.c
parent6717e0d467bea50cb7712e6b5278ddb403fdf828 (diff)
downloadsamba-5693e6c599a586b1bb19eea375c6b1e22526031c.tar.gz
samba-5693e6c599a586b1bb19eea375c6b1e22526031c.tar.bz2
samba-5693e6c599a586b1bb19eea375c6b1e22526031c.zip
r17798: Beginnings of a standalone libaddns library released under
the LGPL. Original code by Krishna Ganugapati <krishnag@centeris.com>. Additional work by me. It's still got some warts, but non-secure updates do currently work. There are at least four things left to really clean up. 1. Change the memory management to use talloc() rather than malloc() and cleanup the leaks. 2. Fix the error code reporting (see initial changes to dnserr.h) 3. Fix the secure updates 4. Define a public interface in addns.h 5. Move the code in libads/dns.c into the libaddns/ directory (and under the LGPL). A few notes: * Enable the new code by compiling with --with-dnsupdate * Also adds the command 'net ads dns register' * Requires -luuid (included in the e2fsprogs-devel package). * Has only been tested on Linux platforms so there may be portability issues. (This used to be commit 36f04674aeefd93c5a0408b8967dcd48b86fdbc1)
Diffstat (limited to 'source3/libaddns/dnsrecord.c')
-rw-r--r--source3/libaddns/dnsrecord.c548
1 files changed, 548 insertions, 0 deletions
diff --git a/source3/libaddns/dnsrecord.c b/source3/libaddns/dnsrecord.c
new file mode 100644
index 0000000000..704d747ee9
--- /dev/null
+++ b/source3/libaddns/dnsrecord.c
@@ -0,0 +1,548 @@
+/*
+ Linux DNS client library implementation
+ Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
+ Copyright (C) 2006 Gerald Carter <jerry@samba.org>
+
+ ** NOTE! The following LGPL license applies to the libaddns
+ ** library. This does NOT imply that all of Samba is released
+ ** under the LGPL
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301 USA
+*/
+
+#include "dns.h"
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateDeleteRecord( char *szHost, int16 wClass,
+ int16 wType, DNS_RR_RECORD ** ppDNSRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( szHost, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRRRecord->RRHeader.dwTTL = 0;
+ pDNSRRRecord->RRHeader.wClass = wClass;
+ pDNSRRRecord->RRHeader.wType = wType;
+ pDNSRRRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRRRecord->RRHeader.wRDataSize = 0;
+
+ *ppDNSRecord = pDNSRRRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pDNSRRRecord );
+ }
+
+ *ppDNSRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateARecord( char *szHost, int16 wClass,
+ int16 wType, int32 dwIP, DNS_RR_RECORD ** ppDNSRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ uint8 *pRData = NULL;
+ int32 dwnIP = 0;
+
+ dwError = DNSDomainNameFromString( szHost, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRRRecord->RRHeader.wType = wType;
+ pDNSRRRecord->RRHeader.pDomainName = pDomainName;
+
+ pDNSRRRecord->RRHeader.wClass = wClass;
+ pDNSRRRecord->RRHeader.wRDataSize = 0;
+ pDNSRRRecord->RRHeader.dwTTL = 0;
+
+ if ( wClass != DNS_CLASS_ANY ) {
+ pDNSRRRecord->RRHeader.dwTTL = DNS_ONE_DAY_IN_SECS;
+ pDNSRRRecord->RRHeader.wRDataSize = sizeof( int32 );
+ dwError =
+ DNSAllocateMemory( sizeof( int32 ),
+ ( void ** ) &pRData );
+ dwnIP = htonl( dwIP );
+ memcpy( pRData, &dwnIP, sizeof( int32 ) );
+ pDNSRRRecord->pRData = pRData;
+ }
+
+ *ppDNSRecord = pDNSRRRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pDNSRRRecord );
+ }
+
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pRData );
+ }
+ *ppDNSRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateTKeyRecord( char *szKeyName, uint8 * pKeyData,
+ int16 wKeySize, DNS_RR_RECORD ** ppDNSRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRecord = NULL;
+ DNS_DOMAIN_NAME *pAlgorithmName = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ time_t t;
+
+ int32 dwRDataSize = 0;
+ int32 dwnInception, dwInception = 0;
+ int32 dwnExpiration, dwExpiration = 0;
+ int16 wnMode, wMode = 0;
+ int16 wnError, wError = 0;
+ int16 wnKeySize = 0;
+ int16 wnOtherSize, wOtherSize = 0;
+
+ int32 dwAlgorithmLen = 0;
+ int32 dwCopied = 0;
+ int32 dwOffset = 0;
+
+ uint8 *pRData = NULL;
+
+ char szTemp[20];
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSDomainNameFromString( szKeyName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ strncpy( szTemp, "gss.microsoft.com", sizeof( szTemp ) );
+ dwError = DNSDomainNameFromString( szTemp, &pAlgorithmName );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRecord->RRHeader.dwTTL = 0;
+ pDNSRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRecord->RRHeader.wClass = DNS_CLASS_ANY;
+ pDNSRecord->RRHeader.wType = QTYPE_TKEY;
+
+ time( &t );
+ dwExpiration = ( int32 ) t + DNS_ONE_DAY_IN_SECS;
+ dwInception = ( int32 ) t;
+ wError = 0;
+ wMode = 3;
+
+ dwError = DNSGetDomainNameLength( pAlgorithmName, &dwAlgorithmLen );
+ BAIL_ON_ERROR( dwError );
+
+ dwRDataSize = dwAlgorithmLen +
+ sizeof( dwExpiration ) + sizeof( dwInception ) +
+ sizeof( wError ) + sizeof( wMode ) + +sizeof( wError ) +
+ sizeof( wKeySize ) + wKeySize + sizeof( wOtherSize ) +
+ wOtherSize;
+
+ dwError = DNSAllocateMemory( dwRDataSize, ( void ** ) &pRData );
+ BAIL_ON_ERROR( dwError );
+
+ dwnInception = htonl( dwInception );
+ dwnExpiration = htonl( dwExpiration );
+ wnMode = htons( wMode );
+ wnError = htons( wError );
+ wnKeySize = htons( wKeySize );
+ wnOtherSize = htons( wOtherSize );
+
+ dwError = DNSCopyDomainName( pRData, pAlgorithmName, &dwCopied );
+ BAIL_ON_ERROR( dwError );
+ dwOffset += dwCopied;
+
+ memcpy( pRData + dwOffset, &dwnInception, sizeof( int32 ) );
+ dwOffset += sizeof( int32 );
+
+ memcpy( pRData + dwOffset, &dwnExpiration, sizeof( int32 ) );
+ dwOffset += sizeof( int32 );
+
+ memcpy( pRData + dwOffset, &wnMode, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &wnError, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &wnKeySize, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, pKeyData, wKeySize );
+ dwOffset += wKeySize;
+
+ memcpy( pRData + dwOffset, &wnOtherSize, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ pDNSRecord->RRHeader.wRDataSize = ( int16 ) dwRDataSize;
+
+ pDNSRecord->pRData = pRData;
+ *ppDNSRecord = pDNSRecord;
+
+ return dwError;
+
+ error:
+
+
+ if ( pDNSRecord ) {
+ DNSFreeMemory( pDNSRecord );
+ }
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+
+ if ( pAlgorithmName ) {
+ DNSFreeDomainName( pAlgorithmName );
+ }
+
+ *ppDNSRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateTSIGRecord( char *szKeyName, int32 dwTimeSigned,
+ int16 wFudge, int16 wOriginalID, uint8 * pMac,
+ int16 wMacSize, DNS_RR_RECORD ** ppDNSRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRecord = NULL;
+ DNS_DOMAIN_NAME *pAlgorithmName = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+ time_t t;
+
+ int32 dwRDataSize = 0;
+
+ int16 wnFudge = 0;
+ int16 wnError = 0, wError = 0;
+ int16 wnMacSize = 0;
+ int16 wnOriginalID = 0;
+ int16 wnOtherLen = 0, wOtherLen = 0;
+
+ int32 dwAlgorithmLen = 0;
+ int32 dwCopied = 0;
+ int32 dwOffset = 0;
+
+ uint8 *pRData = NULL;
+
+ int32 dwnTimeSigned = 0;
+ int16 wnTimePrefix = 0;
+ int16 wTimePrefix = 0;
+
+ char szTemp[20];
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRecord );
+ BAIL_ON_ERROR( dwError );
+
+ dwError = DNSDomainNameFromString( szKeyName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ strncpy( szTemp, "gss.microsoft.com", sizeof( szTemp ) );
+ dwError = DNSDomainNameFromString( szTemp, &pAlgorithmName );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRecord->RRHeader.dwTTL = 0;
+ pDNSRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRecord->RRHeader.wClass = DNS_CLASS_ANY;
+ pDNSRecord->RRHeader.wType = QTYPE_TSIG;
+
+ /* This needs to be a 48bit value - 6 octets. */
+
+ time( &t );
+
+ dwError = DNSGetDomainNameLength( pAlgorithmName, &dwAlgorithmLen );
+ BAIL_ON_ERROR( dwError );
+
+ dwRDataSize = dwAlgorithmLen + 6 + sizeof( wFudge ) + sizeof( wMacSize ) +
+ wMacSize + sizeof( wOriginalID ) + sizeof( wError ) +
+ sizeof( wOtherLen );
+
+ dwError = DNSAllocateMemory( dwRDataSize, ( void ** ) &pRData );
+ BAIL_ON_ERROR( dwError );
+
+ /* Convert t to 48 bit network order */
+
+ wnTimePrefix = htons( wTimePrefix );
+ dwnTimeSigned = htonl( dwTimeSigned );
+ wnFudge = htons( wFudge );
+ wnMacSize = htons( wMacSize );
+ wnOriginalID = htons( wOriginalID );
+ wnError = htons( wError );
+ wnOtherLen = htons( wOtherLen );
+
+ dwError = DNSCopyDomainName( pRData, pAlgorithmName, &dwCopied );
+ BAIL_ON_ERROR( dwError );
+ dwOffset += dwCopied;
+
+ memcpy( pRData + dwOffset, &wnTimePrefix, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &dwnTimeSigned, sizeof( int32 ) );
+ dwOffset += sizeof( int32 );
+
+ memcpy( pRData + dwOffset, &wnFudge, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+
+ memcpy( pRData + dwOffset, &wnMacSize, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, pMac, wMacSize );
+ dwOffset += wMacSize;
+
+ memcpy( pRData + dwOffset, &wnOriginalID, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &wnError, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ memcpy( pRData + dwOffset, &wnOtherLen, sizeof( int16 ) );
+ dwOffset += sizeof( int16 );
+
+ pDNSRecord->RRHeader.wRDataSize = ( int16 ) dwRDataSize;
+
+ pDNSRecord->pRData = pRData;
+ *ppDNSRecord = pDNSRecord;
+
+ return dwError;
+
+ error:
+
+
+ if ( pDNSRecord ) {
+ DNSFreeMemory( pDNSRecord );
+ }
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+
+ if ( pAlgorithmName ) {
+ DNSFreeDomainName( pAlgorithmName );
+ }
+
+ *ppDNSRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateQuestionRecord( char *pszQName, int16 wQType,
+ int16 wQClass,
+ DNS_QUESTION_RECORD ** ppDNSQuestionRecord )
+{
+ int32 dwError = 0;
+ DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( pszQName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_QUESTION_RECORD ),
+ ( void ** ) &pDNSQuestionRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSQuestionRecord->pDomainName = pDomainName;
+ pDNSQuestionRecord->wQueryClass = wQClass;
+ pDNSQuestionRecord->wQueryType = wQType;
+
+ *ppDNSQuestionRecord = pDNSQuestionRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSQuestionRecord ) {
+ DNSFreeMemory( pDNSQuestionRecord );
+ }
+ *ppDNSQuestionRecord = NULL;
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateZoneRecord( char *pszZName, DNS_ZONE_RECORD ** ppDNSZoneRecord )
+{
+ int32 dwError = 0;
+ DNS_ZONE_RECORD *pDNSZoneRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( pszZName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_ZONE_RECORD ),
+ ( void ** ) &pDNSZoneRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSZoneRecord->pDomainName = pDomainName;
+ pDNSZoneRecord->wZoneClass = DNS_CLASS_IN;
+ pDNSZoneRecord->wZoneType = QTYPE_SOA;
+
+ *ppDNSZoneRecord = pDNSZoneRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSZoneRecord ) {
+ DNSFreeMemory( pDNSZoneRecord );
+ }
+ *ppDNSZoneRecord = NULL;
+ return dwError;
+}
+
+int32 DNSFreeZoneRecord( DNS_ZONE_RECORD * pDNSZoneRecord )
+{
+ int32 dwError = 0;
+
+ return dwError;
+
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateNameInUseRecord( char *pszName, int32 qtype,
+ struct in_addr * ip,
+ DNS_RR_RECORD * *ppDNSRRRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( pszName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRRRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRRRecord->RRHeader.dwTTL = 0;
+ pDNSRRRecord->RRHeader.wType = qtype;
+
+ if ( !ip ) {
+ pDNSRRRecord->RRHeader.wClass = DNS_CLASS_ANY;
+ pDNSRRRecord->RRHeader.wRDataSize = 0;
+ } else {
+ pDNSRRRecord->RRHeader.wClass = DNS_CLASS_IN;
+ pDNSRRRecord->RRHeader.wRDataSize = 4;
+ dwError =
+ DNSAllocateMemory( 4,
+ ( void ** ) &pDNSRRRecord->
+ pRData );
+ BAIL_ON_ERROR( dwError );
+ memcpy( pDNSRRRecord->pRData, &ip->s_addr, 4 );
+ }
+
+ *ppDNSRRRecord = pDNSRRRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pDNSRRRecord );
+ }
+ *ppDNSRRRecord = NULL;
+
+ return dwError;
+}
+
+/*********************************************************************
+*********************************************************************/
+
+int32 DNSCreateNameNotInUseRecord( char *pszName, int32 qtype,
+ DNS_RR_RECORD * *ppDNSRRRecord )
+{
+ int32 dwError = 0;
+ DNS_RR_RECORD *pDNSRRRecord = NULL;
+ DNS_DOMAIN_NAME *pDomainName = NULL;
+
+ dwError = DNSDomainNameFromString( pszName, &pDomainName );
+ BAIL_ON_ERROR( dwError );
+
+ dwError =
+ DNSAllocateMemory( sizeof( DNS_RR_RECORD ),
+ ( void ** ) &pDNSRRRecord );
+ BAIL_ON_ERROR( dwError );
+
+ pDNSRRRecord->RRHeader.pDomainName = pDomainName;
+ pDNSRRRecord->RRHeader.wClass = DNS_CLASS_NONE;
+ pDNSRRRecord->RRHeader.wType = qtype;
+ pDNSRRRecord->RRHeader.dwTTL = 0;
+ pDNSRRRecord->RRHeader.wRDataSize = 0;
+
+ *ppDNSRRRecord = pDNSRRRecord;
+
+ return dwError;
+ error:
+
+ if ( pDomainName ) {
+ DNSFreeDomainName( pDomainName );
+ }
+ if ( pDNSRRRecord ) {
+ DNSFreeMemory( pDNSRRRecord );
+ }
+ *ppDNSRRRecord = NULL;
+ return dwError;
+
+}
+