2 Linux DNS client library implementation
4 Copyright (C) 2006 Krishna Ganugapati <krishnag@centeris.com>
5 Copyright (C) 2006 Gerald Carter <jerry@samba.org>
7 ** NOTE! The following LGPL license applies to the libaddns
8 ** library. This does NOT imply that all of Samba is released
11 This library is free software; you can redistribute it and/or
12 modify it under the terms of the GNU Lesser General Public
13 License as published by the Free Software Foundation; either
14 version 2.1 of the License, or (at your option) any later version.
16 This library is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 Lesser General Public License for more details.
21 You should have received a copy of the GNU Lesser General Public
22 License along with this library; if not, write to the Free Software
23 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
39 #include <sys/types.h>
40 #include <sys/socket.h>
41 #include <netinet/in.h>
42 #include <arpa/inet.h>
45 #ifdef HAVE_UUID_UUID_H
46 #include <uuid/uuid.h>
53 #ifdef HAVE_INTTYPES_H
61 #define uint16 uint16_t
69 #define uint32 uint32_t
79 #elif HAVE_GSSAPI_GSSAPI_H
80 #include <gssapi/gssapi.h>
81 #elif HAVE_GSSAPI_GSSAPI_GENERIC_H
82 #include <gssapi/gssapi_generic.h>
85 #if defined(HAVE_GSSAPI_H) || defined(HAVE_GSSAPI_GSSAPI_H) || defined(HAVE_GSSAPI_GSSAPI_GENERIC_H)
86 #define HAVE_GSSAPI_SUPPORT 1
91 #define TALLOC(ctx, size) talloc_named_const(ctx, size, __location__)
92 #define TALLOC_P(ctx, type) (type *)talloc_named_const(ctx, sizeof(type), #type)
93 #define TALLOC_ARRAY(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type)
94 #define TALLOC_MEMDUP(ctx, ptr, size) _talloc_memdup(ctx, ptr, size, __location__)
95 #define TALLOC_ZERO(ctx, size) _talloc_zero(ctx, size, __location__)
96 #define TALLOC_ZERO_P(ctx, type) (type *)_talloc_zero(ctx, sizeof(type), #type)
97 #define TALLOC_ZERO_ARRAY(ctx, type, count) (type *)_talloc_zero_array(ctx, sizeof(type), count, #type)
98 #define TALLOC_REALLOC(ctx, ptr, count) _talloc_realloc(ctx, ptr, count, __location__)
99 #define TALLOC_REALLOC_ARRAY(ctx, ptr, type, count) (type *)_talloc_realloc_array(ctx, ptr, sizeof(type), count, #type)
100 #define TALLOC_FREE(ctx) do { if ((ctx) != NULL) {talloc_free(ctx); ctx=NULL;} } while(0)
102 /*******************************************************************
103 Type definitions for int16, int32, uint16 and uint32. Needed
104 for Samba coding style
105 *******************************************************************/
108 # define uint8 unsigned char
111 #if !defined(int16) && !defined(HAVE_INT16_FROM_RPC_RPC_H)
112 # if (SIZEOF_SHORT == 4)
113 # define int16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16;
114 # else /* SIZEOF_SHORT != 4 */
116 # endif /* SIZEOF_SHORT != 4 */
117 /* needed to work around compile issue on HP-UX 11.x */
122 * Note we duplicate the size tests in the unsigned
123 * case as int16 may be a typedef from rpc/rpc.h
126 #if !defined(uint16) && !defined(HAVE_UINT16_FROM_RPC_RPC_H)
127 # if (SIZEOF_SHORT == 4)
128 # define uint16 __ERROR___CANNOT_DETERMINE_TYPE_FOR_INT16;
129 # else /* SIZEOF_SHORT != 4 */
130 # define uint16 unsigned short
131 # endif /* SIZEOF_SHORT != 4 */
134 #if !defined(int32) && !defined(HAVE_INT32_FROM_RPC_RPC_H)
135 # if (SIZEOF_INT == 4)
137 # elif (SIZEOF_LONG == 4)
139 # elif (SIZEOF_SHORT == 4)
142 /* uggh - no 32 bit type?? probably a CRAY. just hope this works ... */
145 /* needed to work around compile issue on HP-UX 11.x */
150 * Note we duplicate the size tests in the unsigned
151 * case as int32 may be a typedef from rpc/rpc.h
154 #if !defined(uint32) && !defined(HAVE_UINT32_FROM_RPC_RPC_H)
155 # if (SIZEOF_INT == 4)
156 # define uint32 unsigned int
157 # elif (SIZEOF_LONG == 4)
158 # define uint32 unsigned long
159 # elif (SIZEOF_SHORT == 4)
160 # define uint32 unsigned short
162 /* uggh - no 32 bit type?? probably a CRAY. just hope this works ... */
163 # define uint32 unsigned
168 * check for 8 byte long long
172 # if (SIZEOF_LONG == 8)
173 # define uint64 unsigned long
174 # elif (SIZEOF_LONG_LONG == 8)
175 # define uint64 unsigned long long
176 # endif /* don't lie. If we don't have it, then don't use it */
179 /* needed on Sun boxes */
181 #define INADDR_NONE 0xFFFFFFFF
190 #define DNS_OPCODE_UPDATE 1
192 #define BAIL_ON_ERROR(x) \
197 #define BAIL_ON_DNS_ERROR(x) \
198 if ( !ERR_DNS_IS_OK((x)) ) { \
202 #define BAIL_ON_SEC_ERROR(dwMajorStatus) \
203 if ((dwMajorStatus!= GSS_S_COMPLETE)\
204 && (dwMajorStatus != GSS_S_CONTINUE_NEEDED)) {\
208 /* DNS Class Types */
210 #define DNS_CLASS_IN 1
211 #define DNS_CLASS_ANY 255
212 #define DNS_CLASS_NONE 254
218 #define DNS_TCP_PORT 53
219 #define DNS_UDP_PORT 53
224 #define QTYPE_CNAME 5
226 #define QTYPE_ANY 255
227 #define QTYPE_TKEY 249
228 #define QTYPE_TSIG 250
231 MF 4 a mail forwarder (Obsolete - use MX)
232 CNAME 5 the canonical name for an alias
233 SOA 6 marks the start of a zone of authority
234 MB 7 a mailbox domain name (EXPERIMENTAL)
235 MG 8 a mail group member (EXPERIMENTAL)
236 MR 9 a mail rename domain name (EXPERIMENTAL)
237 NULL 10 a null RR (EXPERIMENTAL)
238 WKS 11 a well known service description
239 PTR 12 a domain name pointer
240 HINFO 13 host information
241 MINFO 14 mailbox or mail list information
246 #define QR_QUERY 0x0000
247 #define QR_RESPONSE 0x0001
249 #define OPCODE_QUERY 0x00
250 #define OPCODE_IQUERY 0x01
251 #define OPCODE_STATUS 0x02
255 #define RECURSION_DESIRED 0x01
257 #define RCODE_NOERROR 0
258 #define RCODE_FORMATERROR 1
259 #define RCODE_SERVER_FAILURE 2
260 #define RCODE_NAME_ERROR 3
261 #define RCODE_NOTIMPLEMENTED 4
262 #define RCODE_REFUSED 5
264 #define SENDBUFFER_SIZE 65536
265 #define RECVBUFFER_SIZE 65536
267 #define DNS_ONE_DAY_IN_SECS 86400
268 #define DNS_TEN_HOURS_IN_SECS 36000
270 #define SOCKET_ERROR -1
271 #define INVALID_SOCKET -1
273 #define DNS_NO_ERROR 0
274 #define DNS_FORMAT_ERROR 1
275 #define DNS_SERVER_FAILURE 2
276 #define DNS_NAME_ERROR 3
277 #define DNS_NOT_IMPLEMENTED 4
278 #define DNS_REFUSED 5
288 typedef struct dns_domain_label
{
289 struct dns_domain_label
*pNext
;
295 DNS_DOMAIN_LABEL
*pLabelList
;
299 DNS_DOMAIN_NAME
*pDomainName
;
302 } DNS_QUESTION_RECORD
;
306 DNS_DOMAIN_NAME
*pDomainName
;
313 DNS_DOMAIN_NAME
*pDomainName
;
327 int16 wAlgorithmOffset
;
328 int16 wInceptionOffset
;
329 int16 wExpirationOffset
;
332 int16 wKeySizeOffset
;
333 int16 wKeyDataOffset
;
334 int16 wOtherSizeOffset
;
335 int16 wOtherDataOffset
;
339 int16 wAlgorithmOffset
;
340 int16 wTimeSignedOffset
;
342 int16 wMacSizeOffset
;
343 int16 wMacDataOffset
;
344 int16 wOriginalMessageIdOffset
;
346 int16 wOtherSizeOffset
;
347 int16 wOtherDataOffset
;
352 DNS_RR_HEADER RRHeader
;
354 DNS_TKEY_OFFSETS TKey
;
355 DNS_TSIG_OFFSETS TSig
;
362 int16 wIdentification
;
368 DNS_QUESTION_RECORD
**ppQuestionRRSet
;
369 DNS_RR_RECORD
**ppAnswerRRSet
;
370 DNS_RR_RECORD
**ppAuthorityRRSet
;
371 DNS_RR_RECORD
**ppAdditionalRRSet
;
376 int16 wIdentification
;
382 DNS_ZONE_RECORD
**ppZoneRRSet
;
383 DNS_RR_RECORD
**ppPRRRSet
;
384 DNS_RR_RECORD
**ppUpdateRRSet
;
385 DNS_RR_RECORD
**ppAdditionalRRSet
;
386 } DNS_UPDATE_REQUEST
;
390 int16 wIdentification
;
396 DNS_QUESTION_RECORD
**ppQuestionRRSet
;
397 DNS_RR_RECORD
**ppAnswerRRSet
;
398 DNS_RR_RECORD
**ppAuthorityRRSet
;
399 DNS_RR_RECORD
**ppAdditionalRRSet
;
400 uint8
*pDNSOutBuffer
;
405 int16 wIdentification
;
411 DNS_ZONE_RECORD
**ppZoneRRSet
;
412 DNS_RR_RECORD
**ppPRRRSet
;
413 DNS_RR_RECORD
**ppUpdateRRSet
;
414 DNS_RR_RECORD
**ppAdditionalRRSet
;
415 uint8
*pDNSOutBuffer
;
417 } DNS_UPDATE_RESPONSE
;
422 struct sockaddr RecvAddr
;
423 } DNS_CONNECTION_CONTEXT
;
428 int32 dwBytesWritten
;
429 int32 dwBufferOffset
;
430 } DNS_SENDBUFFER_CONTEXT
;
437 } DNS_RECEIVEBUFFER_CONTEXT
;
439 /* from dnsutils.c */
441 int32
DNSGenerateIdentifier( int16
* pwIdentifer
);
442 int32
DNSGetDomainNameLength( DNS_DOMAIN_NAME
* pDomainName
, int32
* pdwLength
);
443 int32
DNSCopyDomainName( uint8
* pBuffer
, DNS_DOMAIN_NAME
* pDomainName
, int32
* pdwCopied
);
444 int32
DNSAllocateString( char *pszInputString
, char **ppszOutputString
);
445 int32
DNSGenerateKeyName( char **pszKeyName
);
446 int32
DNSMakeRRHeader( DNS_RR_HEADER
* pDNSRR
, char *szOwnerName
, int16 wType
, int32 dwTTL
);
447 int32
DNSDomainNameFromString( const char *pszDomainName
, DNS_DOMAIN_NAME
** ppDomainName
);
448 int32
DNSAppendLabel( DNS_DOMAIN_LABEL
* pLabelList
, DNS_DOMAIN_LABEL
* pLabel
, DNS_DOMAIN_LABEL
** ppNewLabelList
);
449 int32
DNSGenerateKeyName( char **ppszKeyName
);
450 void DNSRecordGenerateOffsets( DNS_RR_RECORD
* pDNSRecord
);
451 int32
MapDNSResponseCodes( int16 wResponseCode
);
452 int32
GetLastError( void );
453 int32
WSAGetLastError( void );
454 int32
DNSAllocateMemory(int32 dwSize
, void * ppMemory
);
455 int32
DNSReallocMemory(void * pMemory
, void * ppNewMemory
, int32 dwSize
);
456 void DNSFreeMemory( void * pMemory
);
457 int32
DNSAllocateString(char *pszInputString
, char **ppszOutputString
);
458 void DNSFreeString(char * pszString
);
459 void DNSFreeDomainName(DNS_DOMAIN_NAME
*pDomainName
);
461 /* from dnsrecord.c */
463 int32
DNSCreateDeleteRecord( char *szHost
, int16 wClass
, int16 wType
, DNS_RR_RECORD
** ppDNSRecord
);
464 int32
DNSCreateARecord( char *szHost
, int16 wClass
, int16 wType
, int32 dwIP
, DNS_RR_RECORD
** ppDNSRecord
);
465 int32
DNSCreateTKeyRecord( char *szKeyName
, uint8
* pKeyData
, int16 dwKeyLen
, DNS_RR_RECORD
** ppDNSRecord
);
466 int32
DNSCreateTSIGRecord( char *szKeyName
, int32 dwTimeSigned
, int16 wFudge
, int16 wOriginalID
, uint8
* pMac
, int16 wMacSize
, DNS_RR_RECORD
** ppDNSRecord
);
467 int32
DNSCreateQuestionRecord( char *pszQName
, int16 wQType
, int16 wQClass
, DNS_QUESTION_RECORD
** ppDNSQuestionRecord
);
468 int32
DNSAddQuestionSection( DNS_REQUEST
* pDNSRequest
, DNS_QUESTION_RECORD
* pDNSQuestion
);
469 int32
DNSAddAdditionalSection( DNS_REQUEST
* pDNSRequest
, DNS_RR_RECORD
* pDNSRecord
);
470 int32
DNSAddAnswerSection( DNS_REQUEST
* pDNSRequest
, DNS_RR_RECORD
* pDNSRecord
);
471 int32
DNSAddAuthoritySection( DNS_REQUEST
* pDNSRequest
, DNS_RR_RECORD
* pDNSRecord
);
472 int32
DNSCreateZoneRecord( const char *pszZName
, DNS_ZONE_RECORD
** ppDNSZoneRecord
);
473 int32
DNSFreeZoneRecord( DNS_ZONE_RECORD
* pDNSZoneRecord
);
474 int32
DNSCreateNameInUseRecord( char *pszName
, int32 qtype
, struct in_addr
*addr
, DNS_RR_RECORD
** ppDNSRRRecord
);
475 int32
DNSCreateNameNotInUseRecord( char *pszName
, int32 qtype
, DNS_RR_RECORD
** ppDNSRRRecord
);
477 /* from dnsresponse.c */
479 int32
DNSStdReceiveStdResponse( HANDLE hDNSHandle
, DNS_RESPONSE
** ppDNSResponse
);
480 int32
DNSUnmarshallDomainName( HANDLE hRecvBuffer
, DNS_DOMAIN_NAME
** ppDomainName
);
481 int32
DNSUnmarshallRRHeader( HANDLE hRecvBuffer
, DNS_RR_HEADER
* pRRHeader
);
482 int32
DNSUnmarshallRData( HANDLE hRecvBuffer
, int32 dwSize
, uint8
** ppRData
, int32
* pdwRead
);
483 int32
DNSUpdateGetResponseCode( DNS_UPDATE_RESPONSE
* pDNSUpdateResponse
, int32
* pdwResponseCode
);
485 /* from dnsrequest.c */
487 int32
DNSStdSendMarshallSection( HANDLE hSendBuffer
, DNS_RR_RECORD
** ppDNSAnswerRRRecords
, int16 wAnswers
);
488 int32
DNSMarshallDomainName( HANDLE hSendBuffer
, DNS_DOMAIN_NAME
* pDomainName
);
489 int32
DNSMarshallRRHeader( HANDLE hSendBuffer
, DNS_RR_RECORD
* pDNSRecord
);
490 int32
DNSMarshallRData( HANDLE hSendBuffer
, DNS_RR_RECORD
* pDNSRecord
);
491 int32
DNSWriteDomainName( HANDLE hDNSHandle
, DNS_DOMAIN_NAME
* pDomainName
);
492 void DNSFreeRequest( DNS_REQUEST
* pDNSRequest
);
493 int32
DNSStdAddQuestionSection( DNS_REQUEST
* pDNSRequest
, DNS_QUESTION_RECORD
* pDNSQuestion
);
494 int32
DNSStdAddAdditionalSection( DNS_REQUEST
* pDNSRequest
, DNS_RR_RECORD
* pDNSRecord
);
495 int32
DNSStdCreateStdRequest( DNS_REQUEST
** ppDNSRequest
);
496 int32
DNSStdSendStdRequest2( HANDLE hDNSServer
, DNS_REQUEST
* pDNSRequest
);
498 /* from dnsuprequest.c */
500 int32
DNSUpdateSendUpdateRequest2( HANDLE hSendBuffer
, DNS_UPDATE_REQUEST
* pDNSRequest
);
501 int32
DNSUpdateBuildRequestMessage( DNS_UPDATE_REQUEST
* pDNSRequest
, HANDLE
* phSendBuffer
);
502 void DNSUpdateFreeRequest( DNS_UPDATE_REQUEST
* pDNSRequest
);
503 int32
DNSWriteDomainName( HANDLE hDNSHandle
, DNS_DOMAIN_NAME
* pDomainName
);
504 void DNSUpdateFreeRequest( DNS_UPDATE_REQUEST
* pDNSRequest
);
505 int32
DNSUpdateAddZoneSection( DNS_UPDATE_REQUEST
* pDNSRequest
, DNS_ZONE_RECORD
* pDNSZone
);
506 int32
DNSUpdateAddAdditionalSection( DNS_UPDATE_REQUEST
* pDNSRequest
, DNS_RR_RECORD
* pDNSRecord
);
507 int32
DNSUpdateAddPRSection( DNS_UPDATE_REQUEST
* pDNSRequest
, DNS_RR_RECORD
* pDNSRecord
);
508 int32
DNSUpdateAddUpdateSection( DNS_UPDATE_REQUEST
* pDNSRequest
, DNS_RR_RECORD
* pDNSRecord
);
509 int32
DNSUpdateCreateUpdateRequest( DNS_UPDATE_REQUEST
** ppDNSRequest
);
513 DNS_ERROR
DNSOpen( char *nameserver
, int32 dwType
, HANDLE
* phDNSServer
);
514 int32
DNSReceiveBufferContext( HANDLE hDNSHandle
, HANDLE hDNSRecvBuffer
, int32
* pdwBytesRead
);
515 int32
DNSCreateSendBuffer( HANDLE
* phDNSSendBuffer
);
516 int32
DNSMarshallBuffer( HANDLE hDNSSendBuffer
, uint8
* pDNSSendBuffer
, int32 dwBufferSize
, int32
* pdwBytesWritten
);
517 int32
DNSSendBufferContext( HANDLE hDNSServer
, HANDLE hSendBuffer
, int32
* pdwBytesSent
);
518 int32
DNSCreateReceiveBuffer( HANDLE
* phDNSRecvBuffer
);
519 int32
DNSUnmarshallBuffer( HANDLE hDNSRecvBuffer
, uint8
* pDNSRecvBuffer
, int32 dwBufferSize
, int32
* pdwBytesRead
);
520 int32
DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer
, int16 wOffset
, DNS_DOMAIN_NAME
** ppDomainName
);
521 int32
DNSReceiveBufferMoveBackIndex( HANDLE hRecvBuffer
, int16 wOffset
);
522 void DNSFreeSendBufferContext( HANDLE hSendBuffer
);
523 int32
DNSGetSendBufferContextSize( HANDLE hSendBuffer
);
524 uint8
*DNSGetSendBufferContextBuffer( HANDLE hSendBuffer
);
529 #ifdef HAVE_GSSAPI_SUPPORT
531 int32
DNSVerifyResponseMessage_GSSSuccess( gss_ctx_id_t
* pGSSContext
, DNS_RR_RECORD
* pClientTKeyRecord
, DNS_RESPONSE
* pDNSResponse
);
532 int32
DNSVerifyResponseMessage_GSSContinue( gss_ctx_id_t
* pGSSContext
, DNS_RR_RECORD
* pClientTKeyRecord
, DNS_RESPONSE
* pDNSResponse
, uint8
** ppServerKeyData
, int16
* pwServerKeyDataSize
);
533 int32
DNSResponseGetRCode( DNS_RESPONSE
* pDNSResponse
, int16
* pwRCode
);
534 int32
DNSResponseGetTSIGRecord( DNS_RESPONSE
* pDNSResponse
, DNS_RR_RECORD
** ppTSIGRecord
);
535 int32
DNSCompareTKeyRecord( DNS_RR_RECORD
* pClientTKeyRecord
, DNS_RR_RECORD
* pTKeyRecord
);
536 int32
DNSBuildTKeyQueryRequest( char *szKeyName
, uint8
* pKeyData
, int32 dwKeyLen
, DNS_REQUEST
** ppDNSRequest
);
537 int32
DNSResponseGetTKeyRecord( DNS_RESPONSE
* pDNSResponse
, DNS_RR_RECORD
** ppTKeyRecord
);
538 int32
DNSGetTKeyData( DNS_RR_RECORD
* pTKeyRecord
, uint8
** ppKeyData
, int16
* pwKeyDataSize
);
539 int32
DNSNegotiateSecureContext( HANDLE hDNSServer
, char *szDomain
, char *szServerName
, char *szKeyName
, gss_ctx_id_t
* pGSSContext
);
540 void display_status( const char *msg
, OM_uint32 maj_stat
, OM_uint32 min_stat
);
541 int32
DNSNegotiateContextAndSecureUpdate( HANDLE hDNSServer
, char *szServiceName
, char *szDomainName
, char *szHost
, int32 dwIPAddress
);
543 #endif /* HAVE_GSSAPI_SUPPORT */
545 /* from dnsupdate.c */
547 int32
DNSSendUpdate( HANDLE hDNSServer
, const char *szDomainName
, char *szHost
, struct in_addr
*iplist
, int num_addrs
, DNS_UPDATE_RESPONSE
** ppDNSUpdateResponse
);
548 int32
DNSBuildSignatureBuffer( int32 dwMaxSignatureSize
, uint8
** ppSignature
);
549 int32
DNSBuildMessageBuffer( DNS_UPDATE_REQUEST
* pDNSUpdateRequest
, char *szKeyName
, int32
* pdwTimeSigned
, int16
* pwFudge
, uint8
** ppMessageBuffer
, int32
* pdwMessageSize
);
550 int32
DNSClose( HANDLE hDNSUpdate
);
552 #ifdef HAVE_GSSAPI_SUPPORT
553 int32
DNSSendSecureUpdate( HANDLE hDNSServer
, gss_ctx_id_t
* pGSSContext
, char *pszKeyName
, char *szDomainName
, char *szHost
, int32 dwIP
, DNS_UPDATE_RESPONSE
** ppDNSUpdateResponse
);
554 int32
DNSUpdateGenerateSignature( gss_ctx_id_t
* pGSSContext
, DNS_UPDATE_REQUEST
* pDNSUpdateRequest
, char *pszKeyName
);
555 #endif /* HAVE_GSSAPI_SUPPORT */
557 /* from dnsupresp.c */
559 int32
DNSUpdateReceiveUpdateResponse( HANDLE hDNSHandle
, DNS_UPDATE_RESPONSE
** ppDNSResponse
);
563 #ifdef HAVE_GSSAPI_SUPPORT
564 int32
DNSGenerateHash( gss_ctx_id_t
* gss_context
, uint8
* pRequestBuffer
, uint8
** ppMAC
, int32
* pdwMacLen
);
565 int32
BuildHashInputBuffer( DNS_REQUEST
* pDNSRequest
, int32 dwLength
, uint8
** ppHashInputBuffer
, int32
* pdwHashInputBufferLen
);
566 int32
DNSStdValidateAndGetTSIGRecord( gss_ctx_id_t
* gss_context
, DNS_RESPONSE
* pDNSResponse
, DNS_RR_RECORD
** ppDNSTSIGRecord
);
567 #endif /* HAVE_GSSAPI_SUPPORT */