diff options
-rw-r--r-- | source3/Makefile.in | 5 | ||||
-rw-r--r-- | source3/libaddns/dns.h | 482 | ||||
-rw-r--r-- | source3/libaddns/dnserr.h | 17 | ||||
-rw-r--r-- | source3/libaddns/dnsgss.c | 620 | ||||
-rw-r--r-- | source3/libaddns/dnsmarshall.c | 531 | ||||
-rw-r--r-- | source3/libaddns/dnsrecord.c | 727 | ||||
-rw-r--r-- | source3/libaddns/dnsrequest.c | 478 | ||||
-rw-r--r-- | source3/libaddns/dnsresponse.c | 589 | ||||
-rw-r--r-- | source3/libaddns/dnssign.c | 56 | ||||
-rw-r--r-- | source3/libaddns/dnssock.c | 771 | ||||
-rw-r--r-- | source3/libaddns/dnsupdate.c | 644 | ||||
-rw-r--r-- | source3/libaddns/dnsuprequest.c | 428 | ||||
-rw-r--r-- | source3/libaddns/dnsupresp.c | 397 | ||||
-rw-r--r-- | source3/libaddns/dnsutils.c | 600 | ||||
-rw-r--r-- | source3/utils/net_ads.c | 206 | ||||
-rw-r--r-- | source3/utils/net_dns.c | 141 |
16 files changed, 1764 insertions, 4928 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index c64e1e0ae6..65c7f5b264 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -268,9 +268,8 @@ PARAM_OBJ = dynconfig.o param/loadparm.o param/params.o lib/sharesec.o KRBCLIENT_OBJ = libads/kerberos.o libads/ads_status.o -LIBADDNS_OBJ0 = libaddns/dnsrecord.o libaddns/dnsrequest.o libaddns/dnsresponse.o \ - libaddns/dnsutils.o libaddns/dnssock.o libaddns/dnsuprequest.o \ - libaddns/dnsupresp.o libaddns/dnsupdate.o libaddns/dnsgss.o +LIBADDNS_OBJ0 = libaddns/dnsrecord.o libaddns/dnsutils.o libaddns/dnssock.o \ + libaddns/dnsgss.o libaddns/dnsmarshall.o LIBADDNS_OBJ = $(LIBADDNS_OBJ0) $(TALLOC_OBJ) LIBGPO_OBJ0 = libgpo/gpo_ldap.o libgpo/gpo_parse.o libgpo/gpo_util.o \ diff --git a/source3/libaddns/dns.h b/source3/libaddns/dns.h index 70c6d0bd22..51af9180d1 100644 --- a/source3/libaddns/dns.h +++ b/source3/libaddns/dns.h @@ -189,22 +189,6 @@ #define DNS_OPCODE_UPDATE 1 -#define BAIL_ON_ERROR(x) \ - if ((x)){ \ - goto error; \ - } - -#define BAIL_ON_DNS_ERROR(x) \ - if ( !ERR_DNS_IS_OK((x)) ) { \ - goto error; \ - } - -#define BAIL_ON_SEC_ERROR(dwMajorStatus) \ - if ((dwMajorStatus!= GSS_S_COMPLETE)\ - && (dwMajorStatus != GSS_S_CONTINUE_NEEDED)) {\ - goto sec_error; \ - } - /* DNS Class Types */ #define DNS_CLASS_IN 1 @@ -264,6 +248,17 @@ TXT 16 text strings #define SENDBUFFER_SIZE 65536 #define RECVBUFFER_SIZE 65536 +/* + * TKEY Modes from rfc2930 + */ + +#define DNS_TKEY_MODE_SERVER 1 +#define DNS_TKEY_MODE_DH 2 +#define DNS_TKEY_MODE_GSSAPI 3 +#define DNS_TKEY_MODE_RESOLVER 4 +#define DNS_TKEY_MODE_DELETE 5 + + #define DNS_ONE_DAY_IN_SECS 86400 #define DNS_TEN_HOURS_IN_SECS 36000 @@ -285,286 +280,219 @@ typedef int BOOL; #endif -typedef struct dns_domain_label { - struct dns_domain_label *pNext; - char *pszLabel; - int32 dwLength; -} DNS_DOMAIN_LABEL; - -typedef struct { - DNS_DOMAIN_LABEL *pLabelList; -} DNS_DOMAIN_NAME; - -typedef struct { - DNS_DOMAIN_NAME *pDomainName; - int16 wQueryType; - int16 wQueryClass; -} DNS_QUESTION_RECORD; - - -typedef struct { - DNS_DOMAIN_NAME *pDomainName; - int16 wZoneType; - int16 wZoneClass; -} DNS_ZONE_RECORD; - - -typedef struct { - DNS_DOMAIN_NAME *pDomainName; - int16 wType; - int16 wClass; - int32 dwTTL; - int16 wRDataSize; - uint8 *pRData; -} DNS_RR_HEADER; - - -typedef struct { - uint8 *pDefData; -} DNS_DEF_RDATA; - -typedef struct { - int16 wAlgorithmOffset; - int16 wInceptionOffset; - int16 wExpirationOffset; - int16 wModeOffset; - int16 wErrorOffset; - int16 wKeySizeOffset; - int16 wKeyDataOffset; - int16 wOtherSizeOffset; - int16 wOtherDataOffset; -} DNS_TKEY_OFFSETS; - -typedef struct { - int16 wAlgorithmOffset; - int16 wTimeSignedOffset; - int16 wFudgeOffset; - int16 wMacSizeOffset; - int16 wMacDataOffset; - int16 wOriginalMessageIdOffset; - int16 wErrorOffset; - int16 wOtherSizeOffset; - int16 wOtherDataOffset; -} DNS_TSIG_OFFSETS; - - -typedef struct { - DNS_RR_HEADER RRHeader; - union { - DNS_TKEY_OFFSETS TKey; - DNS_TSIG_OFFSETS TSig; - } Offsets; - uint8 *pRData; -} DNS_RR_RECORD; - - -typedef struct { - int16 wIdentification; - int16 wParameter; - int16 wQuestions; - int16 wAnswers; - int16 wAuthoritys; - int16 wAdditionals; - DNS_QUESTION_RECORD **ppQuestionRRSet; - DNS_RR_RECORD **ppAnswerRRSet; - DNS_RR_RECORD **ppAuthorityRRSet; - DNS_RR_RECORD **ppAdditionalRRSet; -} DNS_REQUEST; - - -typedef struct { - int16 wIdentification; - int16 wParameter; - int16 wZones; - int16 wPRs; - int16 wUpdates; - int16 wAdditionals; - DNS_ZONE_RECORD **ppZoneRRSet; - DNS_RR_RECORD **ppPRRRSet; - DNS_RR_RECORD **ppUpdateRRSet; - DNS_RR_RECORD **ppAdditionalRRSet; -} DNS_UPDATE_REQUEST; - - -typedef struct { - int16 wIdentification; - int16 wParameter; - int16 wQuestions; - int16 wAnswers; - int16 wAuthoritys; - int16 wAdditionals; - DNS_QUESTION_RECORD **ppQuestionRRSet; - DNS_RR_RECORD **ppAnswerRRSet; - DNS_RR_RECORD **ppAuthorityRRSet; - DNS_RR_RECORD **ppAdditionalRRSet; - uint8 *pDNSOutBuffer; - int32 dwNumBytes; -} DNS_RESPONSE; - -typedef struct { - int16 wIdentification; - int16 wParameter; - int16 wZones; - int16 wPRs; - int16 wUpdates; - int16 wAdditionals; - DNS_ZONE_RECORD **ppZoneRRSet; - DNS_RR_RECORD **ppPRRRSet; - DNS_RR_RECORD **ppUpdateRRSet; - DNS_RR_RECORD **ppAdditionalRRSet; - uint8 *pDNSOutBuffer; - int32 dwNumBytes; -} DNS_UPDATE_RESPONSE; - -typedef struct { +struct dns_domain_label { + struct dns_domain_label *next; + char *label; + size_t len; +}; + +struct dns_domain_name { + struct dns_domain_label *pLabelList; +}; + +struct dns_question { + struct dns_domain_name *name; + uint16 q_type; + uint16 q_class; +}; + +/* + * Before changing the definition of dns_zone, look + * dns_marshall_update_request(), we rely on this being the same as + * dns_question right now. + */ + +struct dns_zone { + struct dns_domain_name *name; + uint16 z_type; + uint16 z_class; +}; + +struct dns_rrec { + struct dns_domain_name *name; + uint16 type; + uint16 r_class; + uint32 ttl; + uint16 data_length; + uint8 *data; +}; + +struct dns_tkey_record { + struct dns_domain_name *algorithm; + time_t inception; + time_t expiration; + uint16 mode; + uint16 error; + uint16 key_length; + uint8 *key; +}; + +struct dns_request { + uint16 id; + uint16 flags; + uint16 num_questions; + uint16 num_answers; + uint16 num_auths; + uint16 num_additionals; + struct dns_question **questions; + struct dns_rrec **answers; + struct dns_rrec **auths; + struct dns_rrec **additionals; +}; + +/* + * Before changing the definition of dns_update_request, look + * dns_marshall_update_request(), we rely on this being the same as + * dns_request right now. + */ + +struct dns_update_request { + uint16 id; + uint16 flags; + uint16 num_zones; + uint16 num_preqs; + uint16 num_updates; + uint16 num_additionals; + struct dns_zone **zones; + struct dns_rrec **preqs; + struct dns_rrec **updates; + struct dns_rrec **additionals; +}; + +struct dns_connection { int32 hType; int s; struct sockaddr RecvAddr; -} DNS_CONNECTION_CONTEXT; - -typedef struct { - uint8 *pSendBuffer; - int32 dwBufferSize; - int32 dwBytesWritten; - int32 dwBufferOffset; -} DNS_SENDBUFFER_CONTEXT; - -typedef struct { - uint8 *pRecvBuffer; - int32 dwBufferSize; - int32 dwBytesRecvd; - int32 dwBytesRead; -} DNS_RECEIVEBUFFER_CONTEXT; +}; + +struct dns_buffer { + uint8 *data; + size_t size; + size_t offset; + DNS_ERROR error; +}; /* from dnsutils.c */ -int32 DNSGenerateIdentifier( int16 * pwIdentifer ); -int32 DNSGetDomainNameLength( DNS_DOMAIN_NAME * pDomainName, int32 * pdwLength ); -int32 DNSCopyDomainName( uint8 * pBuffer, DNS_DOMAIN_NAME * pDomainName, int32 * pdwCopied ); -int32 DNSAllocateString( char *pszInputString, char **ppszOutputString ); -int32 DNSGenerateKeyName( char **pszKeyName ); -int32 DNSMakeRRHeader( DNS_RR_HEADER * pDNSRR, char *szOwnerName, int16 wType, int32 dwTTL ); -int32 DNSDomainNameFromString( const char *pszDomainName, DNS_DOMAIN_NAME ** ppDomainName ); -int32 DNSAppendLabel( DNS_DOMAIN_LABEL * pLabelList, DNS_DOMAIN_LABEL * pLabel, DNS_DOMAIN_LABEL ** ppNewLabelList ); -int32 DNSGenerateKeyName( char **ppszKeyName ); -void DNSRecordGenerateOffsets( DNS_RR_RECORD * pDNSRecord ); -int32 MapDNSResponseCodes( int16 wResponseCode ); -int32 GetLastError( void ); -int32 WSAGetLastError( void ); -int32 DNSAllocateMemory(int32 dwSize, void * ppMemory); -int32 DNSReallocMemory(void * pMemory, void * ppNewMemory, int32 dwSize); -void DNSFreeMemory( void * pMemory ); -int32 DNSAllocateString(char *pszInputString, char **ppszOutputString); -void DNSFreeString(char * pszString); -void DNSFreeDomainName(DNS_DOMAIN_NAME *pDomainName); +DNS_ERROR dns_domain_name_from_string( TALLOC_CTX *mem_ctx, + const char *pszDomainName, + struct dns_domain_name **presult ); +char *dns_generate_keyname( TALLOC_CTX *mem_ctx ); /* from dnsrecord.c */ -int32 DNSCreateDeleteRecord( char *szHost, int16 wClass, int16 wType, DNS_RR_RECORD ** ppDNSRecord ); -int32 DNSCreateARecord( char *szHost, int16 wClass, int16 wType, int32 dwIP, DNS_RR_RECORD ** ppDNSRecord ); -int32 DNSCreateTKeyRecord( char *szKeyName, uint8 * pKeyData, int16 dwKeyLen, DNS_RR_RECORD ** ppDNSRecord ); -int32 DNSCreateTSIGRecord( char *szKeyName, int32 dwTimeSigned, int16 wFudge, int16 wOriginalID, uint8 * pMac, int16 wMacSize, DNS_RR_RECORD ** ppDNSRecord ); -int32 DNSCreateQuestionRecord( char *pszQName, int16 wQType, int16 wQClass, DNS_QUESTION_RECORD ** ppDNSQuestionRecord ); -int32 DNSAddQuestionSection( DNS_REQUEST * pDNSRequest, DNS_QUESTION_RECORD * pDNSQuestion ); -int32 DNSAddAdditionalSection( DNS_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord ); -int32 DNSAddAnswerSection( DNS_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord ); -int32 DNSAddAuthoritySection( DNS_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord ); -int32 DNSCreateZoneRecord( const char *pszZName, DNS_ZONE_RECORD ** ppDNSZoneRecord ); -int32 DNSFreeZoneRecord( DNS_ZONE_RECORD * pDNSZoneRecord ); -int32 DNSCreateNameInUseRecord( char *pszName, int32 qtype, struct in_addr *addr, DNS_RR_RECORD ** ppDNSRRRecord ); -int32 DNSCreateNameNotInUseRecord( char *pszName, int32 qtype, DNS_RR_RECORD ** ppDNSRRRecord ); - -/* from dnsresponse.c */ - -int32 DNSStdReceiveStdResponse( HANDLE hDNSHandle, DNS_RESPONSE ** ppDNSResponse ); -int32 DNSUnmarshallDomainName( HANDLE hRecvBuffer, DNS_DOMAIN_NAME ** ppDomainName ); -int32 DNSUnmarshallRRHeader( HANDLE hRecvBuffer, DNS_RR_HEADER * pRRHeader ); -int32 DNSUnmarshallRData( HANDLE hRecvBuffer, int32 dwSize, uint8 ** ppRData, int32 * pdwRead ); -int32 DNSUpdateGetResponseCode( DNS_UPDATE_RESPONSE * pDNSUpdateResponse, int32 * pdwResponseCode ); - -/* from dnsrequest.c */ - -int32 DNSStdSendMarshallSection( HANDLE hSendBuffer, DNS_RR_RECORD ** ppDNSAnswerRRRecords, int16 wAnswers ); -int32 DNSMarshallDomainName( HANDLE hSendBuffer, DNS_DOMAIN_NAME * pDomainName ); -int32 DNSMarshallRRHeader( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord ); -int32 DNSMarshallRData( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord ); -int32 DNSWriteDomainName( HANDLE hDNSHandle, DNS_DOMAIN_NAME * pDomainName ); -void DNSFreeRequest( DNS_REQUEST * pDNSRequest ); -int32 DNSStdAddQuestionSection( DNS_REQUEST * pDNSRequest, DNS_QUESTION_RECORD * pDNSQuestion ); -int32 DNSStdAddAdditionalSection( DNS_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord ); -int32 DNSStdCreateStdRequest( DNS_REQUEST ** ppDNSRequest ); -int32 DNSStdSendStdRequest2( HANDLE hDNSServer, DNS_REQUEST * pDNSRequest ); - -/* from dnsuprequest.c */ - -int32 DNSUpdateSendUpdateRequest2( HANDLE hSendBuffer, DNS_UPDATE_REQUEST * pDNSRequest ); -int32 DNSUpdateBuildRequestMessage( DNS_UPDATE_REQUEST * pDNSRequest, HANDLE * phSendBuffer ); -void DNSUpdateFreeRequest( DNS_UPDATE_REQUEST * pDNSRequest ); -int32 DNSWriteDomainName( HANDLE hDNSHandle, DNS_DOMAIN_NAME * pDomainName ); -void DNSUpdateFreeRequest( DNS_UPDATE_REQUEST * pDNSRequest ); -int32 DNSUpdateAddZoneSection( DNS_UPDATE_REQUEST * pDNSRequest, DNS_ZONE_RECORD * pDNSZone ); -int32 DNSUpdateAddAdditionalSection( DNS_UPDATE_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord ); -int32 DNSUpdateAddPRSection( DNS_UPDATE_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord ); -int32 DNSUpdateAddUpdateSection( DNS_UPDATE_REQUEST * pDNSRequest, DNS_RR_RECORD * pDNSRecord ); -int32 DNSUpdateCreateUpdateRequest( DNS_UPDATE_REQUEST ** ppDNSRequest ); +DNS_ERROR dns_create_query( TALLOC_CTX *mem_ctx, const char *name, + uint16 q_type, uint16 q_class, + struct dns_request **preq ); +DNS_ERROR dns_create_update( TALLOC_CTX *mem_ctx, const char *name, + struct dns_update_request **preq ); +DNS_ERROR dns_create_probe(TALLOC_CTX *mem_ctx, const char *zone, + const char *host, int num_ips, + const struct in_addr *iplist, + struct dns_update_request **preq); +DNS_ERROR dns_create_rrec(TALLOC_CTX *mem_ctx, const char *name, + uint16 type, uint16 r_class, uint32 ttl, + uint16 data_length, uint8 *data, + struct dns_rrec **prec); +DNS_ERROR dns_add_rrec(TALLOC_CTX *mem_ctx, struct dns_rrec *rec, + uint16 *num_records, struct dns_rrec ***records); +DNS_ERROR dns_create_tkey_record(TALLOC_CTX *mem_ctx, const char *keyname, + const char *algorithm_name, time_t inception, + time_t expiration, uint16 mode, uint16 error, + uint16 key_length, const uint8 *key, + struct dns_rrec **prec); +DNS_ERROR dns_create_name_in_use_record(TALLOC_CTX *mem_ctx, + const char *name, + const in_addr_t *ip, + struct dns_rrec **prec); +DNS_ERROR dns_create_delete_record(TALLOC_CTX *mem_ctx, const char *name, + uint16 type, uint16 r_class, + struct dns_rrec **prec); +DNS_ERROR dns_create_a_record(TALLOC_CTX *mem_ctx, const char *host, + uint32 ttl, in_addr_t ip, + struct dns_rrec **prec); +DNS_ERROR dns_unmarshall_tkey_record(TALLOC_CTX *mem_ctx, struct dns_rrec *rec, + struct dns_tkey_record **ptkey); +DNS_ERROR dns_create_tsig_record(TALLOC_CTX *mem_ctx, const char *keyname, + const char *algorithm_name, + time_t time_signed, uint16 fudge, + uint16 mac_length, const uint8 *mac, + uint16 original_id, uint16 error, + struct dns_rrec **prec); +DNS_ERROR dns_add_rrec(TALLOC_CTX *mem_ctx, struct dns_rrec *rec, + uint16 *num_records, struct dns_rrec ***records); /* from dnssock.c */ -DNS_ERROR DNSOpen( char *nameserver, int32 dwType, HANDLE * phDNSServer ); -int32 DNSReceiveBufferContext( HANDLE hDNSHandle, HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ); -int32 DNSCreateSendBuffer( HANDLE * phDNSSendBuffer ); -int32 DNSMarshallBuffer( HANDLE hDNSSendBuffer, uint8 * pDNSSendBuffer, int32 dwBufferSize, int32 * pdwBytesWritten ); -int32 DNSSendBufferContext( HANDLE hDNSServer, HANDLE hSendBuffer, int32 * pdwBytesSent ); -int32 DNSCreateReceiveBuffer( HANDLE * phDNSRecvBuffer ); -int32 DNSUnmarshallBuffer( HANDLE hDNSRecvBuffer, uint8 * pDNSRecvBuffer, int32 dwBufferSize, int32 * pdwBytesRead ); -int32 DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer, int16 wOffset, DNS_DOMAIN_NAME ** ppDomainName ); -int32 DNSReceiveBufferMoveBackIndex( HANDLE hRecvBuffer, int16 wOffset ); -void DNSFreeSendBufferContext( HANDLE hSendBuffer ); -int32 DNSGetSendBufferContextSize( HANDLE hSendBuffer ); -uint8 *DNSGetSendBufferContextBuffer( HANDLE hSendBuffer ); - +DNS_ERROR dns_open( const char *nameserver, int32 dwType, + TALLOC_CTX *mem_ctx, + struct dns_connection **conn ); +DNS_ERROR dns_send(struct dns_connection *conn, const struct dns_buffer *buf); +DNS_ERROR dns_receive(TALLOC_CTX *mem_ctx, struct dns_connection *conn, + struct dns_buffer **presult); +DNS_ERROR dns_transaction(TALLOC_CTX *mem_ctx, struct dns_connection *conn, + const struct dns_request *req, + struct dns_request **resp); +DNS_ERROR dns_update_transaction(TALLOC_CTX *mem_ctx, + struct dns_connection *conn, + struct dns_update_request *up_req, + struct dns_update_request **up_resp); + +/* from dnsmarshall.c */ + +struct dns_buffer *dns_create_buffer(TALLOC_CTX *mem_ctx); +void dns_marshall_buffer(struct dns_buffer *buf, const uint8 *data, + size_t len); +void dns_marshall_uint16(struct dns_buffer *buf, uint16 val); +void dns_marshall_uint32(struct dns_buffer *buf, uint32 val); +void dns_unmarshall_buffer(struct dns_buffer *buf, uint8 *data, + size_t len); +void dns_unmarshall_uint16(struct dns_buffer *buf, uint16 *val); +void dns_unmarshall_uint32(struct dns_buffer *buf, uint32 *val); +void dns_unmarshall_domain_name(TALLOC_CTX *mem_ctx, + struct dns_buffer *buf, + struct dns_domain_name **pname); +void dns_marshall_domain_name(struct dns_buffer *buf, + const struct dns_domain_name *name); +void dns_unmarshall_domain_name(TALLOC_CTX *mem_ctx, + struct dns_buffer *buf, + struct dns_domain_name **pname); +DNS_ERROR dns_marshall_request(TALLOC_CTX *mem_ctx, + const struct dns_request *req, + struct dns_buffer **pbuf); +DNS_ERROR dns_unmarshall_request(TALLOC_CTX *mem_ctx, + struct dns_buffer *buf, + struct dns_request **preq); +DNS_ERROR dns_marshall_update_request(TALLOC_CTX *mem_ctx, + struct dns_update_request *update, + struct dns_buffer **pbuf); +DNS_ERROR dns_unmarshall_update_request(TALLOC_CTX *mem_ctx, + struct dns_buffer *buf, + struct dns_update_request **pupreq); +struct dns_request *dns_update2request(struct dns_update_request *update); +struct dns_update_request *dns_request2update(struct dns_request *request); +uint16 dns_response_code(uint16 flags); /* from dnsgss.c */ #ifdef HAVE_GSSAPI_SUPPORT -int32 DNSVerifyResponseMessage_GSSSuccess( gss_ctx_id_t * pGSSContext, DNS_RR_RECORD * pClientTKeyRecord, DNS_RESPONSE * pDNSResponse ); -int32 DNSVerifyResponseMessage_GSSContinue( gss_ctx_id_t * pGSSContext, DNS_RR_RECORD * pClientTKeyRecord, DNS_RESPONSE * pDNSResponse, uint8 ** ppServerKeyData, int16 * pwServerKeyDataSize ); -int32 DNSResponseGetRCode( DNS_RESPONSE * pDNSResponse, int16 * pwRCode ); -int32 DNSResponseGetTSIGRecord( DNS_RESPONSE * pDNSResponse, DNS_RR_RECORD ** ppTSIGRecord ); -int32 DNSCompareTKeyRecord( DNS_RR_RECORD * pClientTKeyRecord, DNS_RR_RECORD * pTKeyRecord ); -int32 DNSBuildTKeyQueryRequest( char *szKeyName, uint8 * pKeyData, int32 dwKeyLen, DNS_REQUEST ** ppDNSRequest ); -int32 DNSResponseGetTKeyRecord( DNS_RESPONSE * pDNSResponse, DNS_RR_RECORD ** ppTKeyRecord ); -int32 DNSGetTKeyData( DNS_RR_RECORD * pTKeyRecord, uint8 ** ppKeyData, int16 * pwKeyDataSize ); -int32 DNSNegotiateSecureContext( HANDLE hDNSServer, char *szDomain, char *szServerName, char *szKeyName, gss_ctx_id_t * pGSSContext ); void display_status( const char *msg, OM_uint32 maj_stat, OM_uint32 min_stat ); -int32 DNSNegotiateContextAndSecureUpdate( HANDLE hDNSServer, char *szServiceName, char *szDomainName, char *szHost, int32 dwIPAddress ); +DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, + const char *servername, + const char *keyname, + gss_ctx_id_t *gss_ctx ); +DNS_ERROR dns_sign_update(struct dns_update_request *req, + gss_ctx_id_t gss_ctx, + const char *keyname, + const char *algorithmname, + time_t time_signed, uint16 fudge); +DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx, + const char *domainname, + const char *hostname, + in_addr_t ip_addr, + struct dns_update_request **preq); #endif /* HAVE_GSSAPI_SUPPORT */ -/* from dnsupdate.c */ - -int32 DNSSendUpdate( HANDLE hDNSServer, const char *szDomainName, char *szHost, struct in_addr *iplist, int num_addrs, DNS_UPDATE_RESPONSE ** ppDNSUpdateResponse ); -int32 DNSBuildSignatureBuffer( int32 dwMaxSignatureSize, uint8 ** ppSignature ); -int32 DNSBuildMessageBuffer( DNS_UPDATE_REQUEST * pDNSUpdateRequest, char *szKeyName, int32 * pdwTimeSigned, int16 * pwFudge, uint8 ** ppMessageBuffer, int32 * pdwMessageSize ); -int32 DNSClose( HANDLE hDNSUpdate ); - -#ifdef HAVE_GSSAPI_SUPPORT -int32 DNSSendSecureUpdate( HANDLE hDNSServer, gss_ctx_id_t * pGSSContext, char *pszKeyName, char *szDomainName, char *szHost, int32 dwIP, DNS_UPDATE_RESPONSE ** ppDNSUpdateResponse ); -int32 DNSUpdateGenerateSignature( gss_ctx_id_t * pGSSContext, DNS_UPDATE_REQUEST * pDNSUpdateRequest, char *pszKeyName ); -#endif /* HAVE_GSSAPI_SUPPORT */ - -/* from dnsupresp.c */ - -int32 DNSUpdateReceiveUpdateResponse( HANDLE hDNSHandle, DNS_UPDATE_RESPONSE ** ppDNSResponse ); - -/* from dnssign.c */ - -#ifdef HAVE_GSSAPI_SUPPORT -int32 DNSGenerateHash( gss_ctx_id_t * gss_context, uint8 * pRequestBuffer, uint8 ** ppMAC, int32 * pdwMacLen ); -int32 BuildHashInputBuffer( DNS_REQUEST * pDNSRequest, int32 dwLength, uint8 ** ppHashInputBuffer, int32 * pdwHashInputBufferLen ); -int32 DNSStdValidateAndGetTSIGRecord( gss_ctx_id_t * gss_context, DNS_RESPONSE * pDNSResponse, DNS_RR_RECORD ** ppDNSTSIGRecord ); -#endif /* HAVE_GSSAPI_SUPPORT */ - - #endif /* _DNS_H */ diff --git a/source3/libaddns/dnserr.h b/source3/libaddns/dnserr.h index 013120b652..c46a9831cc 100644 --- a/source3/libaddns/dnserr.h +++ b/source3/libaddns/dnserr.h @@ -37,7 +37,7 @@ /* Setup the DNS_ERROR typedef. Technique takes from nt_status.h */ -#if defined(HAVE_IMMEDIATE_STRUCTURES_XX_DISABLED) +#if defined(HAVE_IMMEDIATE_STRUCTURES) typedef struct {uint32 v;} DNS_ERROR; #define ERROR_DNS(x) ((DNS_ERROR) { x }) #define ERROR_DNS_V(x) ((x).v) @@ -61,6 +61,16 @@ typedef uint32 DNS_ERROR; #define ERROR_DNS_NO_MEMORY ERROR_DNS(4) #define ERROR_DNS_INVALID_NAME_SERVER ERROR_DNS(5) #define ERROR_DNS_CONNECTION_FAILED ERROR_DNS(6) +#define ERROR_DNS_GSS_ERROR ERROR_DNS(7) +#define ERROR_DNS_INVALID_NAME ERROR_DNS(8) +#define ERROR_DNS_INVALID_MESSAGE ERROR_DNS(9) +#define ERROR_DNS_SOCKET_ERROR ERROR_DNS(10) +#define ERROR_DNS_UPDATE_FAILED ERROR_DNS(11) + +/* + * About to be removed, transitional error + */ +#define ERROR_DNS_UNSUCCESSFUL ERROR_DNS(999) #define ERROR_BAD_RESPONSE 1 @@ -70,5 +80,10 @@ typedef uint32 DNS_ERROR; #define ERROR_INVALID_PARAMETER 87 #endif +/* + * About to be removed, transitional error + */ +#define ERROR_UNSUCCESSFUL 999 + #endif /* _DNSERR_H */ diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index 862f5e7b58..fc674a7b81 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -48,507 +48,281 @@ static int strupr( char *szDomainName ) /********************************************************************* *********************************************************************/ -int32 DNSBuildTKeyQueryRequest( char *szKeyName, - uint8 * pKeyData, - int32 dwKeyLen, DNS_REQUEST ** ppDNSRequest ) -{ - int32 dwError = 0; - DNS_RR_RECORD *pDNSTKeyRecord = NULL; - DNS_REQUEST *pDNSRequest = NULL; - DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL; - - dwError = DNSStdCreateStdRequest( &pDNSRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateQuestionRecord( szKeyName, - QTYPE_TKEY, - DNS_CLASS_IN, - &pDNSQuestionRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSStdAddQuestionSection( pDNSRequest, pDNSQuestionRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateTKeyRecord( szKeyName, - pKeyData, - ( int16 ) dwKeyLen, &pDNSTKeyRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSStdAddAdditionalSection( pDNSRequest, pDNSTKeyRecord ); - BAIL_ON_ERROR( dwError ); - - *ppDNSRequest = pDNSRequest; - - return dwError; - - error: - - *ppDNSRequest = NULL; - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSVerifyResponseMessage_GSSSuccess( gss_ctx_id_t * pGSSContext, - DNS_RR_RECORD * pClientTKeyRecord, - DNS_RESPONSE * pDNSResponse ) -{ - int32 dwError = 0; - DNS_RR_RECORD *pTKeyRecord = NULL; - DNS_RR_RECORD *pTSIGRecord = NULL; - int16 wRCode = 0; - - dwError = DNSResponseGetRCode( pDNSResponse, &wRCode ); - BAIL_ON_ERROR( dwError ); - - if ( wRCode != 0 ) { - dwError = ERROR_BAD_RESPONSE; - BAIL_ON_ERROR( dwError ); - - } - - dwError = DNSResponseGetTKeyRecord( pDNSResponse, &pTKeyRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCompareTKeyRecord( pClientTKeyRecord, pTKeyRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSResponseGetTSIGRecord( pDNSResponse, &pTSIGRecord ); - BAIL_ON_ERROR( dwError ); - -/* - dwMajorStatus = GSS_VerifyMIC( - pDNSResponse->pDNSResponseBuffer, - pDNSResponse->dwNumBytes, - pDNSRRRecord->RData.TSIGRData.pMAC, - pDNSRRRecord->RData.TSIGRData.wMaxSize - ) - BAIL_ON_ERROR(dwMajorStatus);*/ - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSVerifyResponseMessage_GSSContinue( gss_ctx_id_t * pGSSContext, - DNS_RR_RECORD * pClientTKeyRecord, - DNS_RESPONSE * pDNSResponse, - uint8 ** ppServerKeyData, - int16 * pwServerKeyDataSize ) +static void display_status_1( const char *m, OM_uint32 code, int type ) { - int32 dwError = 0; - DNS_RR_RECORD *pTKeyRecord = NULL; - int16 wRCode = 0; - uint8 *pServerKeyData = NULL; - int16 wServerKeyDataSize = 0; - + OM_uint32 maj_stat, min_stat; + gss_buffer_desc msg; + OM_uint32 msg_ctx; - dwError = DNSResponseGetRCode( pDNSResponse, &wRCode ); - BAIL_ON_ERROR( dwError ); - if ( wRCode != 0 ) { - dwError = ERROR_BAD_RESPONSE; - BAIL_ON_ERROR( dwError ); + msg_ctx = 0; + while ( 1 ) { + maj_stat = gss_display_status( &min_stat, code, + type, GSS_C_NULL_OID, + &msg_ctx, &msg ); + fprintf( stdout, "GSS-API error %s: %s\n", m, + ( char * ) msg.value ); + ( void ) gss_release_buffer( &min_stat, &msg ); + if ( !msg_ctx ) + break; } - - dwError = DNSResponseGetTKeyRecord( pDNSResponse, &pTKeyRecord ); - BAIL_ON_ERROR( dwError ); - - - dwError = DNSCompareTKeyRecord( pClientTKeyRecord, pTKeyRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSGetTKeyData( pTKeyRecord, - &pServerKeyData, &wServerKeyDataSize ); - BAIL_ON_ERROR( dwError ); - - *ppServerKeyData = pServerKeyData; - *pwServerKeyDataSize = wServerKeyDataSize; - - return dwError; - - error: - - *ppServerKeyData = NULL; - *pwServerKeyDataSize = 0; - return dwError; } /********************************************************************* *********************************************************************/ -int32 DNSResponseGetRCode( DNS_RESPONSE * pDNSResponse, int16 * pwRCode ) +void display_status( const char *msg, OM_uint32 maj_stat, OM_uint32 min_stat ) { - int32 dwError = 0; - int16 wnParameter = 0; - uint8 uChar = 0; - - wnParameter = htons( pDNSResponse->wParameter ); - - /* Byte 0 is the most significate byte - Bit 12, 13, 14, 15 or Bit 4, 5, 6, 7 represent the RCode */ - - memcpy( &uChar, ( uint8 * ) & wnParameter + 1, 1 ); - uChar >>= 4; - *pwRCode = ( int16 ) uChar; - - return dwError; + display_status_1( msg, maj_stat, GSS_C_GSS_CODE ); + display_status_1( msg, min_stat, GSS_C_MECH_CODE ); } -/********************************************************************* -*********************************************************************/ - -int32 DNSResponseGetTKeyRecord( DNS_RESPONSE * pDNSResponse, - DNS_RR_RECORD ** ppTKeyRecord ) +static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx, + struct dns_connection *conn, + const char *keyname, + const gss_name_t target_name, + gss_ctx_id_t *ctx ) { - int32 dwError = 0; - int16 wAnswers = 0; - DNS_RR_RECORD *pDNSRecord = NULL; - int32 i = 0; + struct gss_buffer_desc_struct input_desc, *input_ptr, output_desc; + OM_uint32 major, minor; + OM_uint32 ret_flags; + DNS_ERROR err; + gss_OID_desc krb5_oid_desc = + { 9, (char *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" }; - wAnswers = pDNSResponse->wAnswers; - if ( !wAnswers ) { - dwError = ERROR_INVALID_PARAMETER; - BAIL_ON_ERROR( dwError ); - } + *ctx = GSS_C_NO_CONTEXT; + input_ptr = NULL; - for ( i = 0; i < wAnswers; i++ ) { - pDNSRecord = *( pDNSResponse->ppAnswerRRSet + i ); - if ( pDNSRecord->RRHeader.wType == QTYPE_TKEY ) { - *ppTKeyRecord = pDNSRecord; - return dwError; + do { + major = gss_init_sec_context( + &minor, NULL, ctx, target_name, &krb5_oid_desc, + GSS_C_REPLAY_FLAG | GSS_C_MUTUAL_FLAG | + GSS_C_SEQUENCE_FLAG | GSS_C_CONF_FLAG | + GSS_C_INTEG_FLAG | GSS_C_DELEG_FLAG, + 0, NULL, input_ptr, NULL, &output_desc, + &ret_flags, NULL ); + + if (input_ptr != NULL) { + TALLOC_FREE(input_desc.value); } - } - dwError = ERROR_RECORD_NOT_FOUND; - error: - *ppTKeyRecord = NULL; - return dwError; -} + if (output_desc.length != 0) { -/********************************************************************* -*********************************************************************/ + struct dns_request *req; + struct dns_rrec *rec; + struct dns_buffer *buf; -int32 DNSResponseGetTSIGRecord( DNS_RESPONSE * pDNSResponse, - DNS_RR_RECORD ** ppTSIGRecord ) -{ - int32 dwError = 0; - int16 wAdditionals = 0; - DNS_RR_RECORD *pDNSRecord = NULL; - - int32 i = 0; + time_t t = time(NULL); - wAdditionals = pDNSResponse->wAdditionals; - if ( !wAdditionals ) { - dwError = ERROR_INVALID_PARAMETER; - BAIL_ON_ERROR( dwError ); - } + err = dns_create_query(mem_ctx, keyname, QTYPE_TKEY, + DNS_CLASS_IN, &req); + if (!ERR_DNS_IS_OK(err)) goto error; - for ( i = 0; i < wAdditionals; i++ ) { - pDNSRecord = *( pDNSResponse->ppAdditionalRRSet + i ); - if ( pDNSRecord->RRHeader.wType == QTYPE_TSIG ) { - *ppTSIGRecord = pDNSRecord; - return dwError; - } - } - dwError = ERROR_RECORD_NOT_FOUND; + err = dns_create_tkey_record( + req, keyname, "gss.microsoft.com", t, + t + 86400, DNS_TKEY_MODE_GSSAPI, 0, + output_desc.length, (uint8 *)output_desc.value, + &rec); + if (!ERR_DNS_IS_OK(err)) goto error; - error: - *ppTSIGRecord = NULL; - return dwError; -} + err = dns_add_rrec(req, rec, &req->num_additionals, + &req->additionals); + if (!ERR_DNS_IS_OK(err)) goto error; -/********************************************************************* -*********************************************************************/ + err = dns_marshall_request(req, req, &buf); + if (!ERR_DNS_IS_OK(err)) goto error; -int32 DNSCompareTKeyRecord( DNS_RR_RECORD * pClientTKeyRecord, - DNS_RR_RECORD * pTKeyRecord ) -{ - int32 dwError = 0; + err = dns_send(conn, buf); + if (!ERR_DNS_IS_OK(err)) goto error; - return dwError; -} + TALLOC_FREE(req); + } -/********************************************************************* -*********************************************************************/ + gss_release_buffer(&minor, &output_desc); -int32 DNSNegotiateContextAndSecureUpdate( HANDLE hDNSServer, - char *szServiceName, - char *szDomainName, - char *szHost, int32 dwIPAddress ) -{ - int32 dwError = 0; - char *pszKeyName = NULL; - gss_ctx_id_t ContextHandle = 0; - gss_ctx_id_t *pContextHandle = &ContextHandle; + if ((major != GSS_S_COMPLETE) && + (major != GSS_S_CONTINUE_NEEDED)) { + return ERROR_DNS_GSS_ERROR; + } - dwError = DNSGenerateKeyName( &pszKeyName ); - BAIL_ON_ERROR( dwError ); + if (major == GSS_S_CONTINUE_NEEDED) { - dwError = - DNSNegotiateSecureContext( hDNSServer, szDomainName, szHost, - pszKeyName, pContextHandle ); - BAIL_ON_ERROR( dwError ); + struct dns_request *resp; + struct dns_buffer *buf; + struct dns_tkey_record *tkey; - error: + err = dns_receive(mem_ctx, conn, &buf); + if (!ERR_DNS_IS_OK(err)) goto error; - return dwError; -} + err = dns_unmarshall_request(buf, buf, &resp); + if (!ERR_DNS_IS_OK(err)) goto error; -/********************************************************************* -*********************************************************************/ + /* + * TODO: Compare id and keyname + */ + + if ((resp->num_additionals != 1) || + (resp->answers[0]->type != QTYPE_TKEY)) { + err = ERROR_DNS_INVALID_MESSAGE; + goto error; + } -int32 DNSGetTKeyData( DNS_RR_RECORD * pTKeyRecord, - uint8 ** ppKeyData, int16 * pwKeyDataSize ) -{ - int32 dwError = 0; - int16 wKeyDataSize = 0; - int16 wnKeyDataSize = 0; - int32 dwKeyDataSizeOffset = 0; - int32 dwKeyDataOffset = 0; - uint8 *pKeyData = NULL; + err = dns_unmarshall_tkey_record( + mem_ctx, resp->answers[0], &tkey); + if (!ERR_DNS_IS_OK(err)) goto error; - DNSRecordGenerateOffsets( pTKeyRecord ); - dwKeyDataSizeOffset = pTKeyRecord->Offsets.TKey.wKeySizeOffset; - dwKeyDataOffset = pTKeyRecord->Offsets.TKey.wKeyDataOffset; - memcpy( &wnKeyDataSize, pTKeyRecord->pRData + dwKeyDataSizeOffset, - sizeof( int16 ) ); - wKeyDataSize = ntohs( wnKeyDataSize ); + input_desc.length = tkey->key_length; + input_desc.value = talloc_move(mem_ctx, &tkey->key); - dwError = DNSAllocateMemory( wKeyDataSize, ( void * ) &pKeyData ); - BAIL_ON_ERROR( dwError ); + input_ptr = &input_desc; - memcpy( pKeyData, pTKeyRecord->pRData + dwKeyDataOffset, - wKeyDataSize ); + TALLOC_FREE(buf); + } - *ppKeyData = pKeyData; - *pwKeyDataSize = wKeyDataSize; + } while ( major == GSS_S_CONTINUE_NEEDED ); - return dwError; + /* If we arrive here, we have a valid security context */ + err = ERROR_DNS_SUCCESS; error: - *ppKeyData = NULL; - *pwKeyDataSize = 0; - return dwError; + return err; } -/********************************************************************* -*********************************************************************/ - -int32 DNSNegotiateSecureContext( HANDLE hDNSServer, - char *szDomain, - char *szServerName, - char *szKeyName, gss_ctx_id_t * pGSSContext ) +DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, + const char *servername, + const char *keyname, + gss_ctx_id_t *gss_ctx ) { - int32 dwError = 0; - int32 dwMajorStatus = 0; - char szUpperCaseDomain[256]; - char szTargetName[256]; - DNS_ERROR dns_status; - - gss_buffer_desc input_name; - gss_buffer_desc input_desc, output_desc; - DNS_REQUEST *pDNSRequest = NULL; - DNS_RESPONSE *pDNSResponse = NULL; - DNS_RR_RECORD *pClientTKeyRecord = NULL; - HANDLE hDNSTcpServer = ( HANDLE ) NULL; + OM_uint32 major, minor; - uint8 *pServerKeyData = NULL; - int16 wServerKeyDataSize = 0; + char *upcaserealm, *targetname; + DNS_ERROR err; - OM_uint32 ret_flags = 0; + gss_buffer_desc input_name; + struct dns_connection *conn; - int32 dwMinorStatus = 0; gss_name_t targ_name; - gss_cred_id_t creds; krb5_principal host_principal; - krb5_context ctx = NULL; + krb5_context krb_ctx = NULL; gss_OID_desc nt_host_oid_desc = - { 10, ( char * ) ( ( void * ) "\052\206\110\206\367\022\001\002\002\002" ) }; - gss_OID_desc krb5_oid_desc = - { 9, ( char * ) ( ( void * ) "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02" ) }; + { 10, (char *)"\052\206\110\206\367\022\001\002\002\002" }; - input_desc.value = NULL; - input_desc.length = 0; + TALLOC_CTX *mem_ctx; - dns_status = DNSOpen( szServerName, DNS_TCP, &hDNSTcpServer ); - BAIL_ON_DNS_ERROR( dns_status ); + if (!(mem_ctx = talloc_init("dns_negotiate_sec_ctx"))) { + return ERROR_DNS_NO_MEMORY; + } + err = dns_open( servername, DNS_TCP, mem_ctx, &conn ); + if (!ERR_DNS_IS_OK(err)) goto error; - memset( szUpperCaseDomain, 0, sizeof( szUpperCaseDomain ) ); - memcpy( szUpperCaseDomain, szDomain, strlen( szDomain ) ); - strupr( szUpperCaseDomain ); + if (!(upcaserealm = talloc_strdup(mem_ctx, target_realm))) { + err = ERROR_DNS_NO_MEMORY; + goto error; + } - dwMajorStatus = gss_acquire_cred( ( OM_uint32 * ) & dwMinorStatus, - GSS_C_NO_NAME, - GSS_C_INDEFINITE, - GSS_C_NO_OID_SET, - GSS_C_INITIATE, - &creds, NULL, NULL ); - BAIL_ON_SEC_ERROR( dwMajorStatus ); - printf( "After gss_acquire_cred %d\n", dwMajorStatus ); + strupr(upcaserealm); - sprintf( szTargetName, "dns/%s@%s", szServerName, szUpperCaseDomain ); - printf( "%s\n", szTargetName ); + if (!(targetname = talloc_asprintf(mem_ctx, "dns/%s@%s", + servername, upcaserealm))) { + err = ERROR_DNS_NO_MEMORY; + goto error; + } - krb5_init_context( &ctx ); - krb5_parse_name( ctx, szTargetName, &host_principal ); - krb5_free_context( ctx ); + krb5_init_context( &krb_ctx ); + krb5_parse_name( krb_ctx, targetname, &host_principal ); input_name.value = &host_principal; input_name.length = sizeof( host_principal ); - dwMajorStatus = gss_import_name( ( OM_uint32 * ) & dwMinorStatus, - &input_name, - &nt_host_oid_desc, &targ_name ); - printf( "After gss_import_name %d\n", dwMajorStatus ); - BAIL_ON_SEC_ERROR( dwMajorStatus ); - printf( "After gss_import_name %d\n", dwMajorStatus ); + major = gss_import_name( &minor, &input_name, + &nt_host_oid_desc, &targ_name ); - memset( pGSSContext, 0, sizeof( gss_ctx_id_t ) ); - *pGSSContext = GSS_C_NO_CONTEXT; + krb5_free_principal( krb_ctx, host_principal ); + krb5_free_context( krb_ctx ); - do { - - dwMajorStatus = gss_init_sec_context( ( OM_uint32 * ) & - dwMinorStatus, creds, - pGSSContext, targ_name, - &krb5_oid_desc, - GSS_C_REPLAY_FLAG | - GSS_C_MUTUAL_FLAG | - GSS_C_SEQUENCE_FLAG | - GSS_C_CONF_FLAG | - GSS_C_INTEG_FLAG | - GSS_C_DELEG_FLAG, 0, - NULL, &input_desc, NULL, - &output_desc, - &ret_flags, NULL ); - display_status( "gss_init_context", dwMajorStatus, - dwMinorStatus ); - BAIL_ON_SEC_ERROR( dwMajorStatus ); - printf( "After gss_init_sec_context %d\n", dwMajorStatus ); - - switch ( dwMajorStatus ) { - - case GSS_S_COMPLETE: - if ( output_desc.length != 0 ) { - - dwError = DNSBuildTKeyQueryRequest( szKeyName, - (uint8 *)output_desc. - value, - output_desc. - length, - &pDNSRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSStdSendStdRequest2( hDNSTcpServer, - pDNSRequest ); - BAIL_ON_ERROR( dwError ); - - - dwError = - DNSStdReceiveStdResponse - ( hDNSTcpServer, &pDNSResponse ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSVerifyResponseMessage_GSSSuccess - ( pGSSContext, pClientTKeyRecord, - pDNSResponse ); - BAIL_ON_ERROR( dwError ); - } - break; - - - case GSS_S_CONTINUE_NEEDED: - if ( output_desc.length != 0 ) { - - dwError = DNSBuildTKeyQueryRequest( szKeyName, - (uint8 *)output_desc. - value, - output_desc. - length, - &pDNSRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSStdSendStdRequest2( hDNSTcpServer, - pDNSRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSStdReceiveStdResponse - ( hDNSTcpServer, &pDNSResponse ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSVerifyResponseMessage_GSSContinue - ( pGSSContext, pClientTKeyRecord, - pDNSResponse, &pServerKeyData, - &wServerKeyDataSize ); - BAIL_ON_ERROR( dwError ); - - input_desc.value = pServerKeyData; - input_desc.length = wServerKeyDataSize; - } - break; - - default: - BAIL_ON_ERROR( dwError ); - } + if (major) { + err = ERROR_DNS_GSS_ERROR; + goto error; + } - } while ( dwMajorStatus == GSS_S_CONTINUE_NEEDED ); + err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname, targ_name, + gss_ctx); - /* If we arrive here, we have a valid security context */ - - sec_error: - error: + gss_release_name( &minor, &targ_name ); - return dwError; + error: + TALLOC_FREE(mem_ctx); + return err; } -/********************************************************************* -*********************************************************************/ - -static void display_status_1( const char *m, OM_uint32 code, int type ) +DNS_ERROR dns_sign_update(struct dns_update_request *req, + gss_ctx_id_t gss_ctx, + const char *keyname, + const char *algorithmname, + time_t time_signed, uint16 fudge) { - OM_uint32 maj_stat, min_stat; - gss_buffer_desc msg; - OM_uint32 msg_ctx; - - msg_ctx = 0; - while ( 1 ) { - maj_stat = gss_display_status( &min_stat, code, - type, GSS_C_NULL_OID, - &msg_ctx, &msg ); - fprintf( stdout, "GSS-API error %s: %s\n", m, - ( char * ) msg.value ); - ( void ) gss_release_buffer( &min_stat, &msg ); + struct dns_buffer *buf; + DNS_ERROR err; + struct dns_domain_name *key, *algorithm; + struct gss_buffer_desc_struct msg, mic; + OM_uint32 major, minor; + struct dns_rrec *rec; + + err = dns_marshall_update_request(req, req, &buf); + if (!ERR_DNS_IS_OK(err)) return err; + + err = dns_domain_name_from_string(buf, keyname, &key); + if (!ERR_DNS_IS_OK(err)) goto error; + + err = dns_domain_name_from_string(buf, algorithmname, &algorithm); + if (!ERR_DNS_IS_OK(err)) goto error; + + dns_marshall_domain_name(buf, key); + dns_marshall_uint16(buf, DNS_CLASS_ANY); + dns_marshall_uint32(buf, 0); /* TTL */ + dns_marshall_domain_name(buf, algorithm); + dns_marshall_uint16(buf, 0); /* Time prefix for 48-bit time_t */ + dns_marshall_uint32(buf, time_signed); + dns_marshall_uint16(buf, fudge); + dns_marshall_uint16(buf, 0); /* error */ + dns_marshall_uint16(buf, 0); /* other len */ + + err = buf->error; + if (!ERR_DNS_IS_OK(buf->error)) goto error; + + msg.value = (void *)buf->data; + msg.length = buf->offset; + + major = gss_get_mic(&minor, gss_ctx, 0, &msg, &mic); + if (major != 0) { + err = ERROR_DNS_GSS_ERROR; + goto error; + } - if ( !msg_ctx ) - break; + if (mic.length > 0xffff) { + gss_release_buffer(&minor, &mic); + err = ERROR_DNS_GSS_ERROR; + goto error; } -} -/********************************************************************* -*********************************************************************/ + err = dns_create_tsig_record(buf, keyname, algorithmname, time_signed, + fudge, mic.length, (uint8 *)mic.value, + req->id, 0, &rec); + gss_release_buffer(&minor, &mic); + if (!ERR_DNS_IS_OK(err)) goto error; -void display_status( const char *msg, OM_uint32 maj_stat, OM_uint32 min_stat ) -{ - display_status_1( msg, maj_stat, GSS_C_GSS_CODE ); - display_status_1( msg, min_stat, GSS_C_MECH_CODE ); + err = dns_add_rrec(req, rec, &req->num_additionals, &req->additionals); + + error: + TALLOC_FREE(buf); + return err; } #endif /* HAVE_GSSAPI_SUPPORT */ diff --git a/source3/libaddns/dnsmarshall.c b/source3/libaddns/dnsmarshall.c new file mode 100644 index 0000000000..f23504f201 --- /dev/null +++ b/source3/libaddns/dnsmarshall.c @@ -0,0 +1,531 @@ +/* + Linux DNS client library implementation + 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" +#include "assert.h" + +struct dns_buffer *dns_create_buffer(TALLOC_CTX *mem_ctx) +{ + struct dns_buffer *result; + + if (!(result = talloc(mem_ctx, struct dns_buffer))) { + return NULL; + } + + result->offset = 0; + result->error = ERROR_DNS_SUCCESS; + + /* + * Small inital size to excercise the realloc code + */ + result->size = 2; + + if (!(result->data = TALLOC_ARRAY(result, uint8, result->size))) { + TALLOC_FREE(result); + return NULL; + } + + return result; +} + +void dns_marshall_buffer(struct dns_buffer *buf, const uint8 *data, + size_t len) +{ + if (!ERR_DNS_IS_OK(buf->error)) return; + + if (buf->offset + len < buf->offset) { + /* + * Wraparound! + */ + buf->error = ERROR_DNS_INVALID_PARAMETER; + return; + } + + if ((buf->offset + len) > 0xffff) { + /* + * Only 64k possible + */ + buf->error = ERROR_DNS_INVALID_PARAMETER; + return; + } + + if (buf->offset + len > buf->size) { + size_t new_size = buf->offset + len; + uint8 *new_data; + + /* + * Don't do too many reallocs, round up to some multiple + */ + + new_size += (64 - (new_size % 64)); + + if (!(new_data = TALLOC_REALLOC_ARRAY(buf, buf->data, uint8, + new_size))) { + buf->error = ERROR_DNS_NO_MEMORY; + return; + } + + buf->size = new_size; + buf->data = new_data; + } + + memcpy(buf->data + buf->offset, data, len); + buf->offset += len; + return; +} + +void dns_marshall_uint16(struct dns_buffer *buf, uint16 val) +{ + uint16 n_val = htons(val); + dns_marshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val)); +} + +void dns_marshall_uint32(struct dns_buffer *buf, uint32 val) +{ + uint32 n_val = htonl(val); + dns_marshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val)); +} + +void dns_unmarshall_buffer(struct dns_buffer *buf, uint8 *data, + size_t len) +{ + if (!(ERR_DNS_IS_OK(buf->error))) return; + + if ((len > buf->size) || (buf->offset + len > buf->size)) { + buf->error = ERROR_DNS_INVALID_MESSAGE; + return; + } + + memcpy((void *)data, (const void *)(buf->data + buf->offset), len); + buf->offset += len; + + return; +} + +void dns_unmarshall_uint16(struct dns_buffer *buf, uint16 *val) +{ + uint16 n_val; + + dns_unmarshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val)); + if (!(ERR_DNS_IS_OK(buf->error))) return; + + *val = ntohs(n_val); +} + +void dns_unmarshall_uint32(struct dns_buffer *buf, uint32 *val) +{ + uint32 n_val; + + dns_unmarshall_buffer(buf, (uint8 *)&n_val, sizeof(n_val)); + if (!(ERR_DNS_IS_OK(buf->error))) return; + + *val = ntohl(n_val); +} + +void dns_marshall_domain_name(struct dns_buffer *buf, + const struct dns_domain_name *name) +{ + struct dns_domain_label *label; + char end_char = '\0'; + + /* + * TODO: Implement DNS compression + */ + + for (label = name->pLabelList; label != NULL; label = label->next) { + uint8 len = label->len; + + dns_marshall_buffer(buf, (uint8 *)&len, sizeof(len)); + if (!ERR_DNS_IS_OK(buf->error)) return; + + dns_marshall_buffer(buf, (uint8 *)label->label, len); + if (!ERR_DNS_IS_OK(buf->error)) return; + } + + dns_marshall_buffer(buf, (uint8 *)&end_char, 1); +} + +static void dns_unmarshall_label(TALLOC_CTX *mem_ctx, + int level, + struct dns_buffer *buf, + struct dns_domain_label **plabel) +{ + struct dns_domain_label *label; + uint8 len; + + if (!ERR_DNS_IS_OK(buf->error)) return; + + if (level > 128) { + /* + * Protect against recursion + */ + buf->error = ERROR_DNS_INVALID_MESSAGE; + return; + } + + dns_unmarshall_buffer(buf, &len, sizeof(len)); + if (!ERR_DNS_IS_OK(buf->error)) return; + + if (len == 0) { + *plabel = NULL; + return; + } + + if ((len & 0xc0) == 0xc0) { + /* + * We've got a compressed name. Build up a new "fake" buffer + * and using the calculated offset. + */ + struct dns_buffer new_buf; + uint8 low; + + dns_unmarshall_buffer(buf, &low, sizeof(low)); + if (!ERR_DNS_IS_OK(buf->error)) return; + + new_buf = *buf; + new_buf.offset = len & 0x3f; + new_buf.offset <<= 8; + new_buf.offset |= low; + + dns_unmarshall_label(mem_ctx, level+1, &new_buf, plabel); + buf->error = new_buf.error; + return; + } + + if ((len & 0xc0) != 0) { + buf->error = ERROR_DNS_INVALID_NAME; + return; + } + + if (!(label = talloc(mem_ctx, struct dns_domain_label))) { + buf->error = ERROR_DNS_NO_MEMORY; + return; + } + + label->len = len; + + if (!(label->label = TALLOC_ARRAY(label, char, len+1))) { + buf->error = ERROR_DNS_NO_MEMORY; + goto error; + } + + dns_unmarshall_buffer(buf, (uint8 *)label->label, len); + if (!ERR_DNS_IS_OK(buf->error)) goto error; + + dns_unmarshall_label(label, level+1, buf, &label->next); + if (!ERR_DNS_IS_OK(buf->error)) goto error; + + *plabel = label; + return; + + error: + TALLOC_FREE(label); + return; +} + +void dns_unmarshall_domain_name(TALLOC_CTX *mem_ctx, + struct dns_buffer *buf, + struct dns_domain_name **pname) +{ + struct dns_domain_name *name; + + if (!ERR_DNS_IS_OK(buf->error)) return; + + if (!(name = talloc(mem_ctx, struct dns_domain_name))) { + buf->error = ERROR_DNS_NO_MEMORY; + } + + dns_unmarshall_label(name, 0, buf, &name->pLabelList); + + if (!ERR_DNS_IS_OK(buf->error)) { + return; + } + + *pname = name; + return; +} + +static void dns_marshall_question(struct dns_buffer *buf, + const struct dns_question *q) +{ + dns_marshall_domain_name(buf, q->name); + dns_marshall_uint16(buf, q->q_type); + dns_marshall_uint16(buf, q->q_class); +} + +static void dns_unmarshall_question(TALLOC_CTX *mem_ctx, + struct dns_buffer *buf, + struct dns_question **pq) +{ + struct dns_question *q; + + if (!(ERR_DNS_IS_OK(buf->error))) return; + + if (!(q = talloc(mem_ctx, struct dns_question))) { + buf->error = ERROR_DNS_NO_MEMORY; + return; + } + + dns_unmarshall_domain_name(q, buf, &q->name); + dns_unmarshall_uint16(buf, &q->q_type); + dns_unmarshall_uint16(buf, &q->q_class); + + if (!(ERR_DNS_IS_OK(buf->error))) return; + + *pq = q; +} + +static void dns_marshall_rr(struct dns_buffer *buf, + const struct dns_rrec *r) +{ + dns_marshall_domain_name(buf, r->name); + dns_marshall_uint16(buf, r->type); + dns_marshall_uint16(buf, r->r_class); + dns_marshall_uint32(buf, r->ttl); + dns_marshall_uint16(buf, r->data_length); + dns_marshall_buffer(buf, r->data, r->data_length); +} + +static void dns_unmarshall_rr(TALLOC_CTX *mem_ctx, + struct dns_buffer *buf, + struct dns_rrec **pr) +{ + struct dns_rrec *r; + + if (!(ERR_DNS_IS_OK(buf->error))) return; + + if (!(r = talloc(mem_ctx, struct dns_rrec))) { + buf->error = ERROR_DNS_NO_MEMORY; + return; + } + + dns_unmarshall_domain_name(r, buf, &r->name); + dns_unmarshall_uint16(buf, &r->type); + dns_unmarshall_uint16(buf, &r->r_class); + dns_unmarshall_uint32(buf, &r->ttl); + dns_unmarshall_uint16(buf, &r->data_length); + r->data = NULL; + + if (!(ERR_DNS_IS_OK(buf->error))) return; + + if (r->data_length != 0) { + if (!(r->data = TALLOC_ARRAY(r, uint8, r->data_length))) { + buf->error = ERROR_DNS_NO_MEMORY; + return; + } + dns_unmarshall_buffer(buf, r->data, r->data_length); + } + + if (!(ERR_DNS_IS_OK(buf->error))) return; + + *pr = r; +} + +DNS_ERROR dns_marshall_request(TALLOC_CTX *mem_ctx, + const struct dns_request *req, + struct dns_buffer **pbuf) +{ + struct dns_buffer *buf; + uint16 i; + + if (!(buf = dns_create_buffer(mem_ctx))) { + return ERROR_DNS_NO_MEMORY; + } + + dns_marshall_uint16(buf, req->id); + dns_marshall_uint16(buf, req->flags); + dns_marshall_uint16(buf, req->num_questions); + dns_marshall_uint16(buf, req->num_answers); + dns_marshall_uint16(buf, req->num_auths); + dns_marshall_uint16(buf, req->num_additionals); + + for (i=0; i<req->num_questions; i++) { + dns_marshall_question(buf, req->questions[i]); + } + for (i=0; i<req->num_answers; i++) { + dns_marshall_rr(buf, req->answers[i]); + } + for (i=0; i<req->num_auths; i++) { + dns_marshall_rr(buf, req->auths[i]); + } + for (i=0; i<req->num_additionals; i++) { + dns_marshall_rr(buf, req->additionals[i]); + } + + if (!ERR_DNS_IS_OK(buf->error)) { + DNS_ERROR err = buf->error; + TALLOC_FREE(buf); + return err; + } + + *pbuf = buf; + return ERROR_DNS_SUCCESS; +} + +DNS_ERROR dns_unmarshall_request(TALLOC_CTX *mem_ctx, + struct dns_buffer *buf, + struct dns_request **preq) +{ + struct dns_request *req; + uint16 i; + DNS_ERROR err; + + if (!(req = TALLOC_ZERO_P(mem_ctx, struct dns_request))) { + return ERROR_DNS_NO_MEMORY; + } + + dns_unmarshall_uint16(buf, &req->id); + dns_unmarshall_uint16(buf, &req->flags); + dns_unmarshall_uint16(buf, &req->num_questions); + dns_unmarshall_uint16(buf, &req->num_answers); + dns_unmarshall_uint16(buf, &req->num_auths); + dns_unmarshall_uint16(buf, &req->num_additionals); + + if (!ERR_DNS_IS_OK(buf->error)) goto error; + + err = ERROR_DNS_NO_MEMORY; + + if ((req->num_questions != 0) && + !(req->questions = TALLOC_ARRAY(req, struct dns_question *, + req->num_questions))) { + goto error; + } + if ((req->num_answers != 0) && + !(req->answers = TALLOC_ARRAY(req, struct dns_rrec *, + req->num_answers))) { + goto error; + } + if ((req->num_auths != 0) && + !(req->auths = TALLOC_ARRAY(req, struct dns_rrec *, + req->num_auths))) { + goto error; + } + if ((req->num_additionals != 0) && + !(req->additionals = TALLOC_ARRAY(req, struct dns_rrec *, + req->num_additionals))) { + goto error; + } + + for (i=0; i<req->num_questions; i++) { + dns_unmarshall_question(req->questions, buf, + &req->questions[i]); + } + for (i=0; i<req->num_answers; i++) { + dns_unmarshall_rr(req->answers, buf, + &req->answers[i]); + } + for (i=0; i<req->num_auths; i++) { + dns_unmarshall_rr(req->auths, buf, + &req->auths[i]); + } + for (i=0; i<req->num_additionals; i++) { + dns_unmarshall_rr(req->additionals, buf, + &req->additionals[i]); + } + + if (!ERR_DNS_IS_OK(buf->error)) { + err = buf->error; + goto error; + } + + *preq = req; + return ERROR_DNS_SUCCESS; + + error: + err = buf->error; + TALLOC_FREE(req); + return err; +} + +struct dns_request *dns_update2request(struct dns_update_request *update) +{ + struct dns_request *req; + + /* + * This is a non-specified construct that happens to work on Linux/gcc + * and I would expect it to work everywhere else. dns_request and + * dns_update_request are essentially the same structures with + * different names, so any difference would mean that the compiler + * applied two different variations of padding given the same types in + * the structures. + */ + + req = (struct dns_request *)(void *)update; + + /* + * The assert statement here looks like we could do the equivalent + * assignments to get portable, but it would mean that we have to + * allocate the dns_question record for the dns_zone records. We + * assume that if this assert works then the same holds true for + * dns_zone<>dns_question as well. + */ + +#ifdef DEVELOPER + assert((req->id == update->id) && (req->flags == update->flags) && + (req->num_questions == update->num_zones) && + (req->num_answers == update->num_preqs) && + (req->num_auths == update->num_updates) && + (req->num_additionals == update->num_additionals) && + (req->questions == + (struct dns_question **)(void *)update->zones) && + (req->answers == update->preqs) && + (req->auths == update->updates) && + (req->additionals == update->additionals)); +#endif + + return req; +} + +struct dns_update_request *dns_request2update(struct dns_request *request) +{ + /* + * For portability concerns see dns_update2request; + */ + return (struct dns_update_request *)(void *)request; +} + +DNS_ERROR dns_marshall_update_request(TALLOC_CTX *mem_ctx, + struct dns_update_request *update, + struct dns_buffer **pbuf) +{ + return dns_marshall_request(mem_ctx, dns_update2request(update), pbuf); +} + +DNS_ERROR dns_unmarshall_update_request(TALLOC_CTX *mem_ctx, + struct dns_buffer *buf, + struct dns_update_request **pupreq) +{ + /* + * See comments above about portability. If the above works, this will + * as well. + */ + + return dns_unmarshall_request(mem_ctx, buf, + (struct dns_request **)(void *)pupreq); +} + +uint16 dns_response_code(uint16 flags) +{ + return flags & 0xF; +} diff --git a/source3/libaddns/dnsrecord.c b/source3/libaddns/dnsrecord.c index a840a9079e..6dfb8edf5c 100644 --- a/source3/libaddns/dnsrecord.c +++ b/source3/libaddns/dnsrecord.c @@ -25,524 +25,383 @@ #include "dns.h" -/********************************************************************* -*********************************************************************/ - -int32 DNSCreateDeleteRecord( char *szHost, int16 wClass, - int16 wType, DNS_RR_RECORD ** ppDNSRecord ) +DNS_ERROR dns_create_query( TALLOC_CTX *mem_ctx, const char *name, + uint16 q_type, uint16 q_class, + struct dns_request **preq ) { - 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; + struct dns_request *req; + struct dns_question *q; + DNS_ERROR err; + + if (!(req = TALLOC_ZERO_P(mem_ctx, struct dns_request)) || + !(req->questions = TALLOC_ARRAY(req, struct dns_question *, 1)) || + !(req->questions[0] = talloc(req->questions, + struct dns_question))) { + TALLOC_FREE(req); + return ERROR_DNS_NO_MEMORY; + } - *ppDNSRecord = pDNSRRRecord; + req->id = random(); - return dwError; - error: + req->num_questions = 1; + q = req->questions[0]; - if ( pDomainName ) { - DNSFreeDomainName( pDomainName ); - } - if ( pDNSRRRecord ) { - DNSFreeMemory( pDNSRRRecord ); + err = dns_domain_name_from_string(q, name, &q->name); + if (!ERR_DNS_IS_OK(err)) { + TALLOC_FREE(req); + return err; } - *ppDNSRecord = NULL; - return dwError; -} + q->q_type = q_type; + q->q_class = q_class; -/********************************************************************* -*********************************************************************/ + *preq = req; + return ERROR_DNS_SUCCESS; +} -int32 DNSCreateARecord( char *szHost, int16 wClass, - int16 wType, int32 dwIP, DNS_RR_RECORD ** ppDNSRecord ) +DNS_ERROR dns_create_update( TALLOC_CTX *mem_ctx, const char *name, + struct dns_update_request **preq ) { - 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; + struct dns_update_request *req; + struct dns_zone *z; + DNS_ERROR err; + + if (!(req = TALLOC_ZERO_P(mem_ctx, struct dns_update_request)) || + !(req->zones = TALLOC_ARRAY(req, struct dns_zone *, 1)) || + !(req->zones[0] = talloc(req->zones, struct dns_zone))) { + TALLOC_FREE(req); + return ERROR_DNS_NO_MEMORY; } - *ppDNSRecord = pDNSRRRecord; + req->id = random(); + req->flags = 0x2800; /* Dynamic update */ - return dwError; - error: + req->num_zones = 1; + z = req->zones[0]; - if ( pDomainName ) { - DNSFreeDomainName( pDomainName ); - } - if ( pDNSRRRecord ) { - DNSFreeMemory( pDNSRRRecord ); + err = dns_domain_name_from_string(z, name, &z->name); + if (!ERR_DNS_IS_OK(err)) { + TALLOC_FREE(req); + return err; } - if ( pDNSRRRecord ) { - DNSFreeMemory( pRData ); - } - *ppDNSRecord = NULL; - return dwError; -} + z->z_type = QTYPE_SOA; + z->z_class = DNS_CLASS_IN; -/********************************************************************* -*********************************************************************/ + *preq = req; + return ERROR_DNS_SUCCESS; +} -int32 DNSCreateTKeyRecord( char *szKeyName, uint8 * pKeyData, - int16 wKeySize, DNS_RR_RECORD ** ppDNSRecord ) +DNS_ERROR dns_create_rrec(TALLOC_CTX *mem_ctx, const char *name, + uint16 type, uint16 r_class, uint32 ttl, + uint16 data_length, uint8 *data, + struct dns_rrec **prec) { - 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 ); + struct dns_rrec *rec; + DNS_ERROR err; - 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 (!(rec = talloc(mem_ctx, struct dns_rrec))) { + return ERROR_DNS_NO_MEMORY; } - if ( pDomainName ) { - DNSFreeDomainName( pDomainName ); + err = dns_domain_name_from_string(rec, name, &rec->name); + if (!(ERR_DNS_IS_OK(err))) { + TALLOC_FREE(rec); + return err; } - if ( pAlgorithmName ) { - DNSFreeDomainName( pAlgorithmName ); - } + rec->type = type; + rec->r_class = r_class; + rec->ttl = ttl; + rec->data_length = data_length; + rec->data = talloc_move(rec, &data); - *ppDNSRecord = NULL; - return dwError; + *prec = rec; + return ERROR_DNS_SUCCESS; } -/********************************************************************* -*********************************************************************/ - -int32 DNSCreateTSIGRecord( char *szKeyName, int32 dwTimeSigned, - int16 wFudge, int16 wOriginalID, uint8 * pMac, - int16 wMacSize, DNS_RR_RECORD ** ppDNSRecord ) +DNS_ERROR dns_create_a_record(TALLOC_CTX *mem_ctx, const char *host, + uint32 ttl, in_addr_t ip, + struct dns_rrec **prec) { - 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 ); + uint8 *data; + DNS_ERROR err; - 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; + if (!(data = (uint8 *)TALLOC_MEMDUP(mem_ctx, (const void *)&ip, + sizeof(ip)))) { + return ERROR_DNS_NO_MEMORY; + } - /* This needs to be a 48bit value - 6 octets. */ + err = dns_create_rrec(mem_ctx, host, QTYPE_A, DNS_CLASS_IN, ttl, + sizeof(ip), data, prec); - time( &t ); + if (!ERR_DNS_IS_OK(err)) { + TALLOC_FREE(data); + } - dwError = DNSGetDomainNameLength( pAlgorithmName, &dwAlgorithmLen ); - BAIL_ON_ERROR( dwError ); + return err; +} - dwRDataSize = dwAlgorithmLen + 6 + sizeof( wFudge ) + sizeof( wMacSize ) + - wMacSize + sizeof( wOriginalID ) + sizeof( wError ) + - sizeof( wOtherLen ); +DNS_ERROR dns_create_name_in_use_record(TALLOC_CTX *mem_ctx, + const char *name, + const in_addr_t *ip, + struct dns_rrec **prec) +{ + if (ip != NULL) { + return dns_create_a_record(mem_ctx, name, 0, *ip, prec); + } - dwError = DNSAllocateMemory( dwRDataSize, ( void * ) &pRData ); - BAIL_ON_ERROR( dwError ); + return dns_create_rrec(mem_ctx, name, QTYPE_ANY, DNS_CLASS_IN, 0, 0, + NULL, prec); +} - /* Convert t to 48 bit network order */ +DNS_ERROR dns_create_name_not_in_use_record(TALLOC_CTX *mem_ctx, + const char *name, uint32 type, + struct dns_rrec **prec) +{ + return dns_create_rrec(mem_ctx, name, type, DNS_CLASS_NONE, 0, + 0, NULL, prec); +} - wnTimePrefix = htons( wTimePrefix ); - dwnTimeSigned = htonl( dwTimeSigned ); - wnFudge = htons( wFudge ); - wnMacSize = htons( wMacSize ); - wnOriginalID = htons( wOriginalID ); - wnError = htons( wError ); - wnOtherLen = htons( wOtherLen ); +DNS_ERROR dns_create_delete_record(TALLOC_CTX *mem_ctx, const char *name, + uint16 type, uint16 r_class, + struct dns_rrec **prec) +{ + return dns_create_rrec(mem_ctx, name, type, r_class, 0, 0, NULL, prec); +} - dwError = DNSCopyDomainName( pRData, pAlgorithmName, &dwCopied ); - BAIL_ON_ERROR( dwError ); - dwOffset += dwCopied; +DNS_ERROR dns_create_tkey_record(TALLOC_CTX *mem_ctx, const char *keyname, + const char *algorithm_name, time_t inception, + time_t expiration, uint16 mode, uint16 error, + uint16 key_length, const uint8 *key, + struct dns_rrec **prec) +{ + struct dns_buffer *buf; + struct dns_domain_name *algorithm; + DNS_ERROR err; - memcpy( pRData + dwOffset, &wnTimePrefix, sizeof( int16 ) ); - dwOffset += sizeof( int16 ); + if (!(buf = dns_create_buffer(mem_ctx))) { + return ERROR_DNS_NO_MEMORY; + } - memcpy( pRData + dwOffset, &dwnTimeSigned, sizeof( int32 ) ); - dwOffset += sizeof( int32 ); + err = dns_domain_name_from_string(buf, algorithm_name, &algorithm); + if (!ERR_DNS_IS_OK(err)) goto error; + + dns_marshall_domain_name(buf, algorithm); + dns_marshall_uint32(buf, inception); + dns_marshall_uint32(buf, expiration); + dns_marshall_uint16(buf, mode); + dns_marshall_uint16(buf, error); + dns_marshall_uint16(buf, key_length); + dns_marshall_buffer(buf, key, key_length); + dns_marshall_uint16(buf, 0); /* Other Size */ + + if (!ERR_DNS_IS_OK(buf->error)) { + err = buf->error; + goto error; + } - memcpy( pRData + dwOffset, &wnFudge, sizeof( int16 ) ); - dwOffset += sizeof( int16 ); + err = dns_create_rrec(mem_ctx, keyname, QTYPE_TKEY, DNS_CLASS_ANY, 0, + buf->offset, buf->data, prec); + error: + TALLOC_FREE(buf); + return err; +} - memcpy( pRData + dwOffset, &wnMacSize, sizeof( int16 ) ); - dwOffset += sizeof( int16 ); +DNS_ERROR dns_unmarshall_tkey_record(TALLOC_CTX *mem_ctx, struct dns_rrec *rec, + struct dns_tkey_record **ptkey) +{ + struct dns_tkey_record *tkey; + struct dns_buffer buf; + uint32 tmp_inception, tmp_expiration; + + if (!(tkey = talloc(mem_ctx, struct dns_tkey_record))) { + return ERROR_DNS_NO_MEMORY; + } - memcpy( pRData + dwOffset, pMac, wMacSize ); - dwOffset += wMacSize; + buf.data = rec->data; + buf.size = rec->data_length; + buf.offset = 0; + buf.error = ERROR_DNS_SUCCESS; - memcpy( pRData + dwOffset, &wnOriginalID, sizeof( int16 ) ); - dwOffset += sizeof( int16 ); + dns_unmarshall_domain_name(tkey, &buf, &tkey->algorithm); + dns_unmarshall_uint32(&buf, &tmp_inception); + dns_unmarshall_uint32(&buf, &tmp_expiration); + dns_unmarshall_uint16(&buf, &tkey->mode); + dns_unmarshall_uint16(&buf, &tkey->error); + dns_unmarshall_uint16(&buf, &tkey->key_length); - memcpy( pRData + dwOffset, &wnError, sizeof( int16 ) ); - dwOffset += sizeof( int16 ); + if (!ERR_DNS_IS_OK(buf.error)) goto error; - memcpy( pRData + dwOffset, &wnOtherLen, sizeof( int16 ) ); - dwOffset += sizeof( int16 ); + if (!(tkey->key = TALLOC_ARRAY(tkey, uint8, tkey->key_length))) { + buf.error = ERROR_DNS_NO_MEMORY; + goto error; + } - pDNSRecord->RRHeader.wRDataSize = ( int16 ) dwRDataSize; + dns_unmarshall_buffer(&buf, tkey->key, tkey->key_length); + if (!ERR_DNS_IS_OK(buf.error)) goto error; - pDNSRecord->pRData = pRData; - *ppDNSRecord = pDNSRecord; + tkey->inception = (time_t)tmp_inception; + tkey->expiration = (time_t)tmp_expiration; - return dwError; + *ptkey = tkey; + return ERROR_DNS_SUCCESS; - error: + error: + TALLOC_FREE(tkey); + return buf.error; +} +DNS_ERROR dns_create_tsig_record(TALLOC_CTX *mem_ctx, const char *keyname, + const char *algorithm_name, + time_t time_signed, uint16 fudge, + uint16 mac_length, const uint8 *mac, + uint16 original_id, uint16 error, + struct dns_rrec **prec) +{ + struct dns_buffer *buf; + struct dns_domain_name *algorithm; + DNS_ERROR err; - if ( pDNSRecord ) { - DNSFreeMemory( pDNSRecord ); + if (!(buf = dns_create_buffer(mem_ctx))) { + return ERROR_DNS_NO_MEMORY; } - if ( pDomainName ) { - DNSFreeDomainName( pDomainName ); + err = dns_domain_name_from_string(buf, algorithm_name, &algorithm); + if (!ERR_DNS_IS_OK(err)) goto error; + + dns_marshall_domain_name(buf, algorithm); + dns_marshall_uint16(buf, 0); /* time prefix */ + dns_marshall_uint32(buf, time_signed); + dns_marshall_uint16(buf, fudge); + dns_marshall_uint16(buf, mac_length); + dns_marshall_buffer(buf, mac, mac_length); + dns_marshall_uint16(buf, original_id); + dns_marshall_uint16(buf, error); + dns_marshall_uint16(buf, 0); /* Other Size */ + + if (!ERR_DNS_IS_OK(buf->error)) { + err = buf->error; + goto error; } - if ( pAlgorithmName ) { - DNSFreeDomainName( pAlgorithmName ); - } + err = dns_create_rrec(mem_ctx, keyname, QTYPE_TSIG, DNS_CLASS_ANY, 0, + buf->offset, buf->data, prec); - *ppDNSRecord = NULL; - return dwError; + error: + TALLOC_FREE(buf); + return err; } -/********************************************************************* -*********************************************************************/ - -int32 DNSCreateQuestionRecord( char *pszQName, int16 wQType, - int16 wQClass, - DNS_QUESTION_RECORD ** ppDNSQuestionRecord ) +DNS_ERROR dns_add_rrec(TALLOC_CTX *mem_ctx, struct dns_rrec *rec, + uint16 *num_records, struct dns_rrec ***records) { - 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 ); + struct dns_rrec **new_records; - pDNSQuestionRecord->pDomainName = pDomainName; - pDNSQuestionRecord->wQueryClass = wQClass; - pDNSQuestionRecord->wQueryType = wQType; - - *ppDNSQuestionRecord = pDNSQuestionRecord; + if (!(new_records = TALLOC_REALLOC_ARRAY(mem_ctx, *records, + struct dns_rrec *, + (*num_records)+1))) { + return ERROR_DNS_NO_MEMORY; + } - return dwError; - error: + new_records[*num_records] = talloc_move(new_records, &rec); - if ( pDomainName ) { - DNSFreeDomainName( pDomainName ); - } - if ( pDNSQuestionRecord ) { - DNSFreeMemory( pDNSQuestionRecord ); - } - *ppDNSQuestionRecord = NULL; - return dwError; + *num_records += 1; + *records = new_records; + return ERROR_DNS_SUCCESS; } -/********************************************************************* -*********************************************************************/ - -int32 DNSCreateZoneRecord( const char *pszZName, DNS_ZONE_RECORD ** ppDNSZoneRecord ) +/* + * Create a request that probes a server whether the list of IP addresses + * provides meets our expectations + */ + +DNS_ERROR dns_create_probe(TALLOC_CTX *mem_ctx, const char *zone, + const char *host, int num_ips, + const struct in_addr *iplist, + struct dns_update_request **preq) { - int32 dwError = 0; - DNS_ZONE_RECORD *pDNSZoneRecord = NULL; - DNS_DOMAIN_NAME *pDomainName = NULL; + struct dns_update_request *req; + struct dns_rrec *rec; + DNS_ERROR err; + uint16 i; - dwError = DNSDomainNameFromString( pszZName, &pDomainName ); - BAIL_ON_ERROR( dwError ); + err = dns_create_update(mem_ctx, zone, &req); + if (!ERR_DNS_IS_OK(err)) goto error; - dwError = - DNSAllocateMemory( sizeof( DNS_ZONE_RECORD ), - ( void * ) &pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); + err = dns_create_name_not_in_use_record(req, host, QTYPE_CNAME, &rec); + if (!ERR_DNS_IS_OK(err)) goto error; - pDNSZoneRecord->pDomainName = pDomainName; - pDNSZoneRecord->wZoneClass = DNS_CLASS_IN; - pDNSZoneRecord->wZoneType = QTYPE_SOA; + err = dns_add_rrec(req, rec, &req->num_preqs, &req->preqs); + if (!ERR_DNS_IS_OK(err)) goto error; - *ppDNSZoneRecord = pDNSZoneRecord; + for (i=0; i<num_ips; i++) { + err = dns_create_name_in_use_record(req, host, + &iplist[i].s_addr, &rec); + if (!ERR_DNS_IS_OK(err)) goto error; - return dwError; - error: - - if ( pDomainName ) { - DNSFreeDomainName( pDomainName ); - } - if ( pDNSZoneRecord ) { - DNSFreeMemory( pDNSZoneRecord ); + err = dns_add_rrec(req, rec, &req->num_preqs, &req->preqs); + if (!ERR_DNS_IS_OK(err)) goto error; } - *ppDNSZoneRecord = NULL; - return dwError; -} -int32 DNSFreeZoneRecord( DNS_ZONE_RECORD * pDNSZoneRecord ) -{ - int32 dwError = 0; - - return dwError; + *preq = req; + return ERROR_DNS_SUCCESS; + error: + TALLOC_FREE(req); + return err; } - -/********************************************************************* -*********************************************************************/ - -int32 DNSCreateNameInUseRecord( char *pszName, int32 qtype, - struct in_addr * ip, - DNS_RR_RECORD * *ppDNSRRRecord ) + +DNS_ERROR dns_create_update_request(TALLOC_CTX *mem_ctx, + const char *domainname, + const char *hostname, + in_addr_t ip_addr, + struct dns_update_request **preq) { - 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 ); - } + struct dns_update_request *req; + struct dns_rrec *rec; + DNS_ERROR err; - *ppDNSRRRecord = pDNSRRRecord; + err = dns_create_update(mem_ctx, domainname, &req); + if (!ERR_DNS_IS_OK(err)) return err; - return dwError; - error: + /* + * The zone must be used at all + */ - if ( pDomainName ) { - DNSFreeDomainName( pDomainName ); - } - if ( pDNSRRRecord ) { - DNSFreeMemory( pDNSRRRecord ); - } - *ppDNSRRRecord = NULL; + err = dns_create_rrec(req, domainname, QTYPE_ANY, DNS_CLASS_ANY, + 0, 0, NULL, &rec); + if (!ERR_DNS_IS_OK(err)) goto error; - return dwError; -} + err = dns_add_rrec(req, rec, &req->num_preqs, &req->preqs); + if (!ERR_DNS_IS_OK(err)) goto error; -/********************************************************************* -*********************************************************************/ + /* + * Delete any existing A records + */ -int32 DNSCreateNameNotInUseRecord( char *pszName, int32 qtype, - DNS_RR_RECORD * *ppDNSRRRecord ) -{ - int32 dwError = 0; - DNS_RR_RECORD *pDNSRRRecord = NULL; - DNS_DOMAIN_NAME *pDomainName = NULL; + err = dns_create_delete_record(req, hostname, QTYPE_A, DNS_CLASS_ANY, + &rec); + if (!ERR_DNS_IS_OK(err)) goto error; + + err = dns_add_rrec(req, rec, &req->num_updates, &req->updates); + if (!ERR_DNS_IS_OK(err)) goto error; - dwError = DNSDomainNameFromString( pszName, &pDomainName ); - BAIL_ON_ERROR( dwError ); + /* + * .. and add our IP + */ - dwError = - DNSAllocateMemory( sizeof( DNS_RR_RECORD ), - ( void * ) &pDNSRRRecord ); - BAIL_ON_ERROR( dwError ); + err = dns_create_a_record(req, hostname, 3600, ip_addr, &rec); + if (!ERR_DNS_IS_OK(err)) goto error; - pDNSRRRecord->RRHeader.pDomainName = pDomainName; - pDNSRRRecord->RRHeader.wClass = DNS_CLASS_NONE; - pDNSRRRecord->RRHeader.wType = qtype; - pDNSRRRecord->RRHeader.dwTTL = 0; - pDNSRRRecord->RRHeader.wRDataSize = 0; + err = dns_add_rrec(req, rec, &req->num_updates, &req->updates); + if (!ERR_DNS_IS_OK(err)) goto error; - *ppDNSRRRecord = pDNSRRRecord; - - return dwError; - error: - - if ( pDomainName ) { - DNSFreeDomainName( pDomainName ); - } - if ( pDNSRRRecord ) { - DNSFreeMemory( pDNSRRRecord ); - } - *ppDNSRRRecord = NULL; - return dwError; + *preq = req; + return ERROR_DNS_SUCCESS; + error: + TALLOC_FREE(req); + return err; } - diff --git a/source3/libaddns/dnsrequest.c b/source3/libaddns/dnsrequest.c deleted file mode 100644 index d92b0737d3..0000000000 --- a/source3/libaddns/dnsrequest.c +++ /dev/null @@ -1,478 +0,0 @@ -/* - 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" - -/********************************************************************* -*********************************************************************/ - -static int32 DNSStdMarshallQuestionSection( HANDLE hSendBuffer, - DNS_QUESTION_RECORD ** ppDNSQuestionRecords, - int16 wQuestions ) -{ - int32 dwError = 0; - int32 i = 0; - int32 dwRead = 0; - DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL; - int16 wnQueryType = 0; - int16 wnQueryClass = 0; - - for ( i = 0; i < wQuestions; i++ ) { - - pDNSQuestionRecord = *( ppDNSQuestionRecords + i ); - dwError = - DNSMarshallDomainName( hSendBuffer, - pDNSQuestionRecord-> - pDomainName ); - BAIL_ON_ERROR( dwError ); - - wnQueryType = htons( pDNSQuestionRecord->wQueryType ); - dwError = - DNSMarshallBuffer( hSendBuffer, - ( uint8 * ) & wnQueryType, - ( int32 ) sizeof( int16 ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - - wnQueryClass = htons( pDNSQuestionRecord->wQueryClass ); - dwError = - DNSMarshallBuffer( hSendBuffer, - ( uint8 * ) & wnQueryClass, - ( int32 ) sizeof( int16 ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - - pDNSQuestionRecord++; - } - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSStdMarshallAnswerSection( HANDLE hSendBuffer, - DNS_RR_RECORD ** ppDNSAnswerRRRecords, - int16 wAnswers ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSAnswerRRRecord = NULL; - - - for ( i = 0; i < wAnswers; i++ ) { - - pDNSAnswerRRRecord = *( ppDNSAnswerRRRecords + i ); - - dwError = - DNSMarshallRRHeader( hSendBuffer, - pDNSAnswerRRRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSMarshallRData( hSendBuffer, pDNSAnswerRRRecord ); - BAIL_ON_ERROR( dwError ); - - pDNSAnswerRRRecord++; - - } - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSStdMarshallAuthoritySection( HANDLE hSendBuffer, - DNS_RR_RECORD ** ppDNSAuthorityRRRecords, - int16 wAuthoritys ) -{ - int32 dwError = 0; - int32 i = 0; - - DNS_RR_RECORD *pDNSAuthorityRRRecord = NULL; - - for ( i = 0; i < wAuthoritys; i++ ) { - - pDNSAuthorityRRRecord = *( ppDNSAuthorityRRRecords + i ); - - dwError = - DNSMarshallRRHeader( hSendBuffer, - pDNSAuthorityRRRecord ); - - dwError = DNSMarshallRData( hSendBuffer, - pDNSAuthorityRRRecord ); - BAIL_ON_ERROR( dwError ); - - } - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSStdMarshallAdditionalSection( HANDLE hSendBuffer, - DNS_RR_RECORD ** ppDNSAdditionalsRRRecords, - int16 wAdditionals ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSAdditionalRRRecord = NULL; - - for ( i = 0; i < wAdditionals; i++ ) { - - pDNSAdditionalRRRecord = *( ppDNSAdditionalsRRRecords + i ); - - dwError = - DNSMarshallRRHeader( hSendBuffer, - pDNSAdditionalRRRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSMarshallRData( hSendBuffer, - pDNSAdditionalRRRecord ); - BAIL_ON_ERROR( dwError ); - - } - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSBuildRequestMessage( DNS_REQUEST * pDNSRequest, HANDLE * phSendBuffer ) -{ - int32 dwError = 0; - char DNSMessageHeader[12]; - int16 wnIdentification = 0; - int16 wnParameter = 0; - int16 wnQuestions = 0; - int16 wnAnswers = 0; - int16 wnAuthoritys = 0; - int16 wnAdditionals = 0; - int32 dwRead = 0; - HANDLE hSendBuffer = ( HANDLE ) NULL; - - dwError = DNSCreateSendBuffer( &hSendBuffer ); - BAIL_ON_ERROR( dwError ); - - wnIdentification = htons( pDNSRequest->wIdentification ); - memcpy( DNSMessageHeader, ( char * ) &wnIdentification, 2 ); - - wnParameter = htons( pDNSRequest->wParameter ); - memcpy( DNSMessageHeader + 2, ( char * ) &wnParameter, 2 ); - - wnQuestions = htons( pDNSRequest->wQuestions ); - memcpy( DNSMessageHeader + 4, ( char * ) &wnQuestions, 2 ); - - wnAnswers = htons( pDNSRequest->wAnswers ); - memcpy( DNSMessageHeader + 6, ( char * ) &wnAnswers, 2 ); - - wnAuthoritys = htons( pDNSRequest->wAuthoritys ); - memcpy( DNSMessageHeader + 8, ( char * ) &wnAuthoritys, 2 ); - - wnAdditionals = htons( pDNSRequest->wAdditionals ); - memcpy( DNSMessageHeader + 10, ( char * ) &wnAdditionals, 2 ); - - dwError = - DNSMarshallBuffer( hSendBuffer, ( uint8 * ) DNSMessageHeader, - 12, &dwRead ); - BAIL_ON_ERROR( dwError ); - - if ( pDNSRequest->wQuestions ) { - dwError = - DNSStdMarshallQuestionSection( hSendBuffer, - pDNSRequest-> - ppQuestionRRSet, - pDNSRequest-> - wQuestions ); - BAIL_ON_ERROR( dwError ); - } - - if ( pDNSRequest->wAnswers ) { - dwError = - DNSStdMarshallAnswerSection( hSendBuffer, - pDNSRequest-> - ppAnswerRRSet, - pDNSRequest->wAnswers ); - BAIL_ON_ERROR( dwError ); - } - - if ( pDNSRequest->wAuthoritys ) { - dwError = - DNSStdMarshallAuthoritySection( hSendBuffer, - pDNSRequest-> - ppAuthorityRRSet, - pDNSRequest-> - wAuthoritys ); - BAIL_ON_ERROR( dwError ); - } - - if ( pDNSRequest->wAdditionals ) { - dwError = - DNSStdMarshallAdditionalSection( hSendBuffer, - pDNSRequest-> - ppAdditionalRRSet, - pDNSRequest-> - wAdditionals ); - BAIL_ON_ERROR( dwError ); - } -#if 0 - DNSDumpSendBufferContext( hSendBuffer ); -#endif - *phSendBuffer = hSendBuffer; - - return dwError; - - error: - - if ( hSendBuffer ) { - DNSFreeSendBufferContext( hSendBuffer ); - } - - *phSendBuffer = ( HANDLE ) NULL; - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSStdSendStdRequest2( HANDLE hDNSServer, DNS_REQUEST * pDNSRequest ) -{ - int32 dwError = 0; - int32 dwBytesSent = 0; - HANDLE hSendBuffer = ( HANDLE ) NULL; - - dwError = DNSBuildRequestMessage( pDNSRequest, &hSendBuffer ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSSendBufferContext( hDNSServer, hSendBuffer, &dwBytesSent ); - BAIL_ON_ERROR( dwError ); - - error: - - if ( hSendBuffer ) { - DNSFreeSendBufferContext( hSendBuffer ); - } - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSMarshallDomainName( HANDLE hSendBuffer, DNS_DOMAIN_NAME * pDomainName ) -{ - int32 dwError = 0; - DNS_DOMAIN_LABEL *pTemp = NULL; - int32 dwLen = 0; - int32 dwSent = 0; - char uEndChar = 0; - - pTemp = pDomainName->pLabelList; - while ( pTemp ) { - dwLen = ( int32 ) strlen( pTemp->pszLabel ); - dwError = - DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & dwLen, - sizeof( char ), &dwSent ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSMarshallBuffer( hSendBuffer, - ( uint8 * ) pTemp->pszLabel, dwLen, - &dwSent ); - BAIL_ON_ERROR( dwError ); - pTemp = pTemp->pNext; - } - DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & uEndChar, - sizeof( char ), &dwSent ); - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSMarshallRRHeader( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord ) -{ - int32 dwError = 0; - int32 dwRead = 0; - int16 wnType = 0; - int16 wnClass = 0; - int16 wnRDataSize = 0; - int32 dwnTTL = 0; - - dwError = - DNSMarshallDomainName( hSendBuffer, - pDNSRecord->RRHeader.pDomainName ); - BAIL_ON_ERROR( dwError ); - - wnType = htons( pDNSRecord->RRHeader.wType ); - dwError = - DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & wnType, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - - wnClass = htons( pDNSRecord->RRHeader.wClass ); - dwError = - DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & wnClass, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - - dwnTTL = htonl( pDNSRecord->RRHeader.dwTTL ); - dwError = - DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & dwnTTL, - sizeof( int32 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - - wnRDataSize = htons( pDNSRecord->RRHeader.wRDataSize ); - dwError = - DNSMarshallBuffer( hSendBuffer, ( uint8 * ) & wnRDataSize, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSMarshallRData( HANDLE hSendBuffer, DNS_RR_RECORD * pDNSRecord ) -{ - int32 dwError = 0; - int32 dwWritten = 0; - - dwError = - DNSMarshallBuffer( hSendBuffer, pDNSRecord->pRData, - pDNSRecord->RRHeader.wRDataSize, - &dwWritten ); - BAIL_ON_ERROR( dwError ); - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSStdAddQuestionSection( DNS_REQUEST * pDNSRequest, - DNS_QUESTION_RECORD * pDNSQuestion ) -{ - int32 dwNumQuestions = 0; - int32 dwError = 0; - - dwNumQuestions = pDNSRequest->wQuestions; - - dwError = DNSReallocMemory( ( uint8 * ) pDNSRequest->ppQuestionRRSet, - ( void * ) &pDNSRequest->ppQuestionRRSet, - ( dwNumQuestions + - 1 ) * sizeof( DNS_QUESTION_RECORD * ) - ); - BAIL_ON_ERROR( dwError ); - - *( pDNSRequest->ppQuestionRRSet + dwNumQuestions ) = pDNSQuestion; - - pDNSRequest->wQuestions += 1; - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSStdAddAdditionalSection( DNS_REQUEST * pDNSRequest, - DNS_RR_RECORD * pDNSRecord ) -{ - int32 dwNumAdditionals = 0; - int32 dwError = 0; - - dwNumAdditionals = pDNSRequest->wAdditionals; - dwError = DNSReallocMemory( pDNSRequest->ppAdditionalRRSet, - ( void * ) &pDNSRequest-> - ppAdditionalRRSet, - ( dwNumAdditionals + - 1 ) * sizeof( DNS_RR_RECORD * ) ); - BAIL_ON_ERROR( dwError ); - - *( pDNSRequest->ppAdditionalRRSet + dwNumAdditionals ) = pDNSRecord; - - pDNSRequest->wAdditionals += 1; - - error: - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSStdCreateStdRequest( DNS_REQUEST ** ppDNSRequest ) -{ - int32 dwError = 0; - DNS_REQUEST *pDNSRequest = NULL; - -#if 0 - int16 wRecursionDesired = RECURSION_DESIRED; - int16 wParameter = QR_QUERY; - int16 wOpcode = OPCODE_QUERY; -#endif - dwError = - DNSAllocateMemory( sizeof( DNS_REQUEST ), - ( void * ) &pDNSRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSGenerateIdentifier( &pDNSRequest->wIdentification ); - BAIL_ON_ERROR( dwError ); - -/* - wOpcode <<= 1; - wRecursionDesired <<= 7; - wParameter |= wOpcode; - wParameter |= wRecursionDesired; -*/ - pDNSRequest->wParameter = 0x00; - - *ppDNSRequest = pDNSRequest; - - return dwError; - - error: - - *ppDNSRequest = NULL; - return dwError; -} diff --git a/source3/libaddns/dnsresponse.c b/source3/libaddns/dnsresponse.c deleted file mode 100644 index 9a5ff7dee7..0000000000 --- a/source3/libaddns/dnsresponse.c +++ /dev/null @@ -1,589 +0,0 @@ -/* - 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" - -/********************************************************************* -*********************************************************************/ - -static int32 DNSStdAllocateResponse( DNS_RESPONSE ** ppDNSResponse ) -{ - int32 dwError = 0; - DNS_RESPONSE *pDNSResponse = NULL; - - dwError = - DNSAllocateMemory( sizeof( DNS_RESPONSE ), - ( void * ) &pDNSResponse ); - BAIL_ON_ERROR( dwError ); - - *ppDNSResponse = pDNSResponse; - - return dwError; - - error: - - *ppDNSResponse = NULL; - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSStdUnmarshallQuestionSection( HANDLE hReceiveBuffer, - int16 wQuestions, - DNS_QUESTION_RECORD * - **pppDNSQuestionRecords ) -{ - int32 dwError = 0; - int32 i = 0; - int32 dwRead = 0; - DNS_QUESTION_RECORD *pDNSQuestionRecord = NULL; - DNS_QUESTION_RECORD **ppDNSQuestionRecords = NULL; - int16 wnQueryClass = 0; - int16 wnQueryType = 0; - - - dwError = - DNSAllocateMemory( wQuestions * - sizeof( DNS_QUESTION_RECORD * ), - ( void * ) &ppDNSQuestionRecords ); - BAIL_ON_ERROR( dwError ); - - for ( i = 0; i < wQuestions; i++ ) { - - dwError = - DNSAllocateMemory( sizeof( DNS_QUESTION_RECORD ), - ( void * ) &pDNSQuestionRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUnmarshallDomainName( hReceiveBuffer, - &pDNSQuestionRecord-> - pDomainName ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUnmarshallBuffer( hReceiveBuffer, - ( uint8 * ) & wnQueryType, - ( int32 ) sizeof( int16 ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - pDNSQuestionRecord->wQueryType = ntohs( wnQueryType ); - - dwError = - DNSUnmarshallBuffer( hReceiveBuffer, - ( uint8 * ) & wnQueryClass, - ( int32 ) sizeof( int16 ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - pDNSQuestionRecord->wQueryClass = ntohs( wnQueryClass ); - - *( ppDNSQuestionRecords + i ) = pDNSQuestionRecord; - } - - *pppDNSQuestionRecords = ppDNSQuestionRecords; - return dwError; - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSStdUnmarshallAnswerSection( HANDLE hReceiveBuffer, - int16 wAnswers, - DNS_RR_RECORD * **pppDNSAnswerRRRecords ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSRRRecord = NULL; - DNS_RR_RECORD **ppDNSAnswerRRRecords = NULL; - DNS_RR_HEADER RRHeader = { 0 }; - DNS_RR_HEADER *pRRHeader = &RRHeader; - uint8 *pRData = NULL; - int32 dwRead = 0; - - dwError = DNSAllocateMemory( wAnswers * sizeof( DNS_RR_RECORD * ), - ( void * ) &ppDNSAnswerRRRecords ); - BAIL_ON_ERROR( dwError ); - - for ( i = 0; i < wAnswers; i++ ) { - - memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) ); - dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader ); - BAIL_ON_ERROR( dwError ); - - - dwError = - DNSUnmarshallRData( hReceiveBuffer, - pRRHeader->wRDataSize, &pRData, - &dwRead ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_RR_RECORD ), - ( void * ) &pDNSRRRecord ); - BAIL_ON_ERROR( dwError ); - - memcpy( &pDNSRRRecord->RRHeader, pRRHeader, - sizeof( DNS_RR_HEADER ) ); - pDNSRRRecord->pRData = pRData; - - *( ppDNSAnswerRRRecords + i ) = pDNSRRRecord; - } - - *pppDNSAnswerRRRecords = ppDNSAnswerRRRecords; - - return dwError; - - error: - - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSStdUnmarshallAuthoritySection( HANDLE hReceiveBuffer, - int16 wAuthoritys, - DNS_RR_RECORD * **pppDNSAuthorityRRRecords ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSRRRecord = NULL; - DNS_RR_RECORD **ppDNSAuthorityRRRecords = NULL; - DNS_RR_HEADER RRHeader = { 0 }; - DNS_RR_HEADER *pRRHeader = &RRHeader; - uint8 *pRData = NULL; - int32 dwRead = 0; - - dwError = DNSAllocateMemory( wAuthoritys * sizeof( DNS_RR_RECORD * ), - ( void * ) &ppDNSAuthorityRRRecords ); - BAIL_ON_ERROR( dwError ); - - for ( i = 0; i < wAuthoritys; i++ ) { - - memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) ); - dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUnmarshallRData( hReceiveBuffer, - pRRHeader->wRDataSize, &pRData, - &dwRead ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_RR_RECORD ), - ( void * ) &pDNSRRRecord ); - BAIL_ON_ERROR( dwError ); - - memcpy( &pDNSRRRecord->RRHeader, pRRHeader, - sizeof( DNS_RR_HEADER ) ); - pDNSRRRecord->pRData = pRData; - - *( ppDNSAuthorityRRRecords + i ) = pDNSRRRecord; - } - - *pppDNSAuthorityRRRecords = ppDNSAuthorityRRRecords; - - return dwError; - - error: - - return dwError; - -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSStdUnmarshallAdditionalSection( HANDLE hReceiveBuffer, - int16 wAdditionals, - DNS_RR_RECORD * - **pppDNSAdditionalsRRRecords ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSRRRecord = NULL; - DNS_RR_RECORD **ppDNSAdditionalRRRecords = NULL; - DNS_RR_HEADER RRHeader = { 0 }; - DNS_RR_HEADER *pRRHeader = &RRHeader; - uint8 *pRData = NULL; - int32 dwRead = 0; - - dwError = DNSAllocateMemory( wAdditionals * sizeof( DNS_RR_RECORD * ), - ( void * ) &ppDNSAdditionalRRRecords ); - BAIL_ON_ERROR( dwError ); - - for ( i = 0; i < wAdditionals; i++ ) { - - memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) ); - dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUnmarshallRData( hReceiveBuffer, - pRRHeader->wRDataSize, &pRData, - &dwRead ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_RR_RECORD ), - ( void * ) &pDNSRRRecord ); - BAIL_ON_ERROR( dwError ); - - memcpy( &pDNSRRRecord->RRHeader, pRRHeader, - sizeof( DNS_RR_HEADER ) ); - pDNSRRRecord->pRData = pRData; - - - *( ppDNSAdditionalRRRecords + i ) = pDNSRRRecord; - } - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSStdReceiveStdResponse( HANDLE hDNSHandle, DNS_RESPONSE ** ppDNSResponse ) -{ - DNS_RESPONSE *pDNSResponse = NULL; - int32 dwError = 0; - int16 wnIdentification, wIdentification = 0; - int16 wnParameter, wParameter = 0; - int16 wnQuestions, wQuestions = 0; - int16 wnAnswers, wAnswers = 0; - int16 wnAdditionals, wAdditionals = 0; - int16 wnAuthoritys, wAuthoritys = 0; - int32 dwRead = 0; - DNS_RR_RECORD **ppDNSAnswerRecords = NULL; - DNS_RR_RECORD **ppDNSAdditionalRecords = NULL; - DNS_RR_RECORD **ppDNSAuthorityRecords = NULL; - DNS_QUESTION_RECORD **ppDNSQuestionRecords = NULL; - HANDLE hRecvBuffer = ( HANDLE ) NULL; - - dwError = DNSCreateReceiveBuffer( &hRecvBuffer ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSReceiveBufferContext( hDNSHandle, hRecvBuffer, &dwRead ); - BAIL_ON_ERROR( dwError ); - -#if 0 - dwError = DNSDumpRecvBufferContext( hRecvBuffer ); - BAIL_ON_ERROR( dwError ); -#endif - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, - ( uint8 * ) & wnIdentification, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wIdentification = ntohs( wnIdentification ); - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnParameter, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wParameter = ntohs( wnParameter ); - - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnQuestions, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wQuestions = ntohs( wnQuestions ); - - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAnswers, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wAnswers = ntohs( wnAnswers ); - - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAuthoritys, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wAuthoritys = ntohs( wnAuthoritys ); - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAdditionals, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wAdditionals = ntohs( wnAdditionals ); - - - if ( wQuestions ) { - dwError = - DNSStdUnmarshallQuestionSection( hRecvBuffer, - wQuestions, - &ppDNSQuestionRecords ); - BAIL_ON_ERROR( dwError ); - } - - if ( wAnswers ) { - dwError = - DNSStdUnmarshallAnswerSection( hRecvBuffer, wAnswers, - &ppDNSAnswerRecords ); - BAIL_ON_ERROR( dwError ); - } - - if ( wAuthoritys ) { - dwError = - DNSStdUnmarshallAuthoritySection( hRecvBuffer, - wAuthoritys, - &ppDNSAuthorityRecords ); - BAIL_ON_ERROR( dwError ); - } - - if ( wAdditionals ) { - dwError = - DNSStdUnmarshallAdditionalSection( hRecvBuffer, - wAdditionals, - &ppDNSAdditionalRecords ); - BAIL_ON_ERROR( dwError ); - } - - dwError = DNSStdAllocateResponse( &pDNSResponse ); - BAIL_ON_ERROR( dwError ); - - pDNSResponse->wIdentification = wIdentification; - pDNSResponse->wParameter = wParameter; - pDNSResponse->wQuestions = wQuestions; - pDNSResponse->wAnswers = wAnswers; - pDNSResponse->wAuthoritys = wAuthoritys; - pDNSResponse->wAdditionals = wAdditionals; - - pDNSResponse->ppQuestionRRSet = ppDNSQuestionRecords; - pDNSResponse->ppAnswerRRSet = ppDNSAnswerRecords; - pDNSResponse->ppAuthorityRRSet = ppDNSAuthorityRecords; - pDNSResponse->ppAdditionalRRSet = ppDNSAdditionalRecords; - - *ppDNSResponse = pDNSResponse; - - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUnmarshallDomainName( HANDLE hRecvBuffer, DNS_DOMAIN_NAME ** ppDomainName ) -{ - int32 dwError = 0; - DNS_DOMAIN_LABEL *pLabel = NULL; - DNS_DOMAIN_LABEL *pLabelList = NULL; - DNS_DOMAIN_NAME *pDomainName = NULL; - char *pszLabel = NULL; - char szLabel[65]; - uint8 uLen = 0; - int32 dwRead = 0; - uint8 uLen1, uLen2 = 0; - int16 wnOffset, wOffset = 0; - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, &uLen1, sizeof( char ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - if ( uLen1 & 0xC0 ) { - - uLen1 |= 0x3F; - dwError = - DNSUnmarshallBuffer( hRecvBuffer, &uLen2, - sizeof( char ), &dwRead ); - BAIL_ON_ERROR( dwError ); - - memcpy( ( uint8 * ) & wnOffset, &uLen1, sizeof( char ) ); - memcpy( ( uint8 * ) & wnOffset + 1, &uLen2, sizeof( char ) ); - wOffset = ntohs( wnOffset ); - - dwError = - DNSUnmarshallDomainNameAtOffset( hRecvBuffer, wOffset, - &pDomainName ); - BAIL_ON_ERROR( dwError ); - *ppDomainName = pDomainName; - - return dwError; - - } else { - - dwError = DNSReceiveBufferMoveBackIndex( hRecvBuffer, 1 ); - BAIL_ON_ERROR( dwError ); - - while ( 1 ) { - - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, &uLen, - sizeof( char ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - if ( uLen == 0 ) { - break; - } - - memset( szLabel, 0, 65 ); - dwError = - DNSUnmarshallBuffer( hRecvBuffer, - ( uint8 * ) szLabel, - uLen, &dwRead ); - - dwError = DNSAllocateString( szLabel, &pszLabel ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ), - ( void * ) &pLabel ); - BAIL_ON_ERROR( dwError ); - - pLabel->pszLabel = pszLabel; - dwError = - DNSAppendLabel( pLabelList, pLabel, - &pLabelList ); - BAIL_ON_ERROR( dwError ); - } - - } - - dwError = - DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ), - ( void * ) &pDomainName ); - BAIL_ON_ERROR( dwError ); - pDomainName->pLabelList = pLabelList; - - *ppDomainName = pDomainName; - - return dwError; - - error: - - *ppDomainName = NULL; - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUnmarshallRRHeader( HANDLE hRecvBuffer, DNS_RR_HEADER * pRRHeader ) -{ - int32 dwError = 0; - int32 dwRead = 0; - int16 wnType = 0; - int16 wnClass = 0; - int16 wnRDataSize = 0; - int32 dwnTTL = 0; - - dwError = - DNSUnmarshallDomainName( hRecvBuffer, - &pRRHeader->pDomainName ); - BAIL_ON_ERROR( dwError ); - - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnType, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - pRRHeader->wType = ntohs( wnType ); - - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnClass, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - pRRHeader->wClass = ntohs( wnClass ); - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & dwnTTL, - sizeof( int32 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - pRRHeader->dwTTL = ntohl( dwnTTL ); - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnRDataSize, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - pRRHeader->wRDataSize = htons( wnRDataSize ); - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUnmarshallRData( HANDLE hRecvBuffer, - int32 dwSize, uint8 ** ppRData, int32 * pdwRead ) -{ - int32 dwError = 0; - uint8 *pMemory = NULL; - - dwError = DNSAllocateMemory( dwSize, ( void * ) &pMemory ); - BAIL_ON_ERROR( dwError ); - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) pMemory, dwSize, - pdwRead ); - BAIL_ON_ERROR( dwError ); - - *ppRData = pMemory; - - return dwError; - - error: - - if ( pMemory ) { - DNSFreeMemory( pMemory ); - } - - *ppRData = NULL; - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateGetResponseCode( DNS_UPDATE_RESPONSE * pDNSUpdateResponse, - int32 * pdwResponseCode ) -{ - int32 dwError = 0; - - *pdwResponseCode = - MapDNSResponseCodes( pDNSUpdateResponse->wParameter ); - - return dwError; -} - diff --git a/source3/libaddns/dnssign.c b/source3/libaddns/dnssign.c deleted file mode 100644 index 3a30e0df7e..0000000000 --- a/source3/libaddns/dnssign.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - 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" - - -#ifdef HAVE_GSSAPI_SUPPORT - -/********************************************************************* -*********************************************************************/ - -int32 DNSStdValidateAndGetTSIGRecord( gss_ctx_id_t * gss_context, - DNS_RESPONSE * pDNSResponse, - DNS_RR_RECORD ** ppDNSTSIGRecord ) -{ - int32 dwError = 0; - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateValidateAndGetTSIGRecord( gss_ctx_id_t * gss_context, - DNS_UPDATE_RESPONSE * pDNSUpdateResponse, - DNS_RR_RECORD ** ppDNSTSIGRecord ) -{ - int32 dwError = 0; - - return dwError; -} - -#endif diff --git a/source3/libaddns/dnssock.c b/source3/libaddns/dnssock.c index ac66a6d1b4..597a7ebf07 100644 --- a/source3/libaddns/dnssock.c +++ b/source3/libaddns/dnssock.c @@ -26,88 +26,95 @@ #include "dns.h" #include <sys/time.h> +#include <unistd.h> + +static int destroy_dns_connection(struct dns_connection *conn) +{ + return close(conn->s); +} /******************************************************************** ********************************************************************/ -static DNS_ERROR DNSTCPOpen( char *nameserver, HANDLE * phDNSServer ) +static DNS_ERROR dns_tcp_open( const char *nameserver, + TALLOC_CTX *mem_ctx, + struct dns_connection **result ) { - DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER; - int sockServer; - unsigned long ulAddress; + uint32_t ulAddress; struct hostent *pHost; struct sockaddr_in s_in; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + struct dns_connection *conn; + int res; - if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) { + if (!(conn = talloc(mem_ctx, struct dns_connection))) { return ERROR_DNS_NO_MEMORY; } if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) { if ( (pHost = gethostbyname( nameserver )) == NULL ) { - dwError = ERROR_DNS_INVALID_NAME_SERVER; - BAIL_ON_DNS_ERROR( dwError ); + TALLOC_FREE(conn); + return ERROR_DNS_INVALID_NAME_SERVER; } memcpy( &ulAddress, pHost->h_addr, pHost->h_length ); } - if ( (sockServer = socket( PF_INET, SOCK_STREAM, 0 )) == INVALID_SOCKET ) { - dwError = ERROR_DNS_NO_MEMORY; - BAIL_ON_DNS_ERROR( dwError ); + conn->s = socket( PF_INET, SOCK_STREAM, 0 ); + if (conn->s == -1) { + TALLOC_FREE(conn); + return ERROR_DNS_CONNECTION_FAILED; } + talloc_set_destructor(conn, destroy_dns_connection); + s_in.sin_family = AF_INET; s_in.sin_addr.s_addr = ulAddress; s_in.sin_port = htons( DNS_TCP_PORT ); - if ( (connect( sockServer, (struct sockaddr*)&s_in, sizeof( s_in ))) == SOCKET_ERROR ) { - dwError = ERROR_DNS_CONNECTION_FAILED; - BAIL_ON_DNS_ERROR( dwError ); + res = connect(conn->s, (struct sockaddr*)&s_in, sizeof( s_in )); + if (res == -1) { + TALLOC_FREE(conn); + return ERROR_DNS_CONNECTION_FAILED; } - - pDNSContext->s = sockServer; - pDNSContext->hType = DNS_TCP; - - *phDNSServer = ( HANDLE ) pDNSContext; - dwError = ERROR_DNS_SUCCESS; + conn->hType = DNS_TCP; - return dwError; - -error: - TALLOC_FREE( pDNSContext ); - *phDNSServer = ( HANDLE ) NULL; - - return dwError; + *result = conn; + return ERROR_DNS_SUCCESS; } /******************************************************************** ********************************************************************/ -static DNS_ERROR DNSUDPOpen( char *nameserver, HANDLE * phDNSServer ) +static DNS_ERROR dns_udp_open( const char *nameserver, + TALLOC_CTX *mem_ctx, + struct dns_connection **result ) { - DNS_ERROR dwError = ERROR_DNS_INVALID_PARAMETER; - int SendSocket; unsigned long ulAddress; struct hostent *pHost; struct sockaddr_in RecvAddr; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; + struct dns_connection *conn; - if ( (pDNSContext = TALLOC_P( NULL, DNS_CONNECTION_CONTEXT )) == NULL ) { + if (!(conn = talloc(NULL, struct dns_connection))) { return ERROR_DNS_NO_MEMORY; } if ( (ulAddress = inet_addr( nameserver )) == INADDR_NONE ) { if ( (pHost = gethostbyname( nameserver )) == NULL ) { - dwError = ERROR_DNS_INVALID_NAME_SERVER; - BAIL_ON_DNS_ERROR( dwError ); + TALLOC_FREE(conn); + return ERROR_DNS_INVALID_NAME_SERVER; } memcpy( &ulAddress, pHost->h_addr, pHost->h_length ); } /* Create a socket for sending data */ - SendSocket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + conn->s = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); + if (conn->s == -1) { + TALLOC_FREE(conn); + return ERROR_DNS_CONNECTION_FAILED; + } + + talloc_set_destructor(conn, destroy_dns_connection); /* Set up the RecvAddr structure with the IP address of the receiver (in this example case "123.456.789.1") @@ -117,651 +124,237 @@ static DNS_ERROR DNSUDPOpen( char *nameserver, HANDLE * phDNSServer ) RecvAddr.sin_port = htons( DNS_UDP_PORT ); RecvAddr.sin_addr.s_addr = ulAddress; - pDNSContext->s = SendSocket; - pDNSContext->hType = DNS_UDP; - memcpy( &pDNSContext->RecvAddr, &RecvAddr, sizeof( struct sockaddr_in ) ); - - *phDNSServer = ( HANDLE ) pDNSContext; - - dwError = ERROR_DNS_SUCCESS; + conn->hType = DNS_UDP; + memcpy( &conn->RecvAddr, &RecvAddr, sizeof( struct sockaddr_in ) ); - return dwError; - -error: - TALLOC_FREE( pDNSContext ); - *phDNSServer = ( HANDLE ) NULL; - - return dwError; + *result = conn; + return ERROR_DNS_SUCCESS; } /******************************************************************** ********************************************************************/ -DNS_ERROR DNSOpen( char *nameserver, int32 dwType, HANDLE * phDNSServer ) +DNS_ERROR dns_open( const char *nameserver, int32 dwType, + TALLOC_CTX *mem_ctx, + struct dns_connection **conn ) { switch ( dwType ) { case DNS_TCP: - return DNSTCPOpen( nameserver, phDNSServer ); + return dns_tcp_open( nameserver, mem_ctx, conn ); case DNS_UDP: - return DNSUDPOpen( nameserver, phDNSServer ); + return dns_udp_open( nameserver, mem_ctx, conn ); } return ERROR_DNS_INVALID_PARAMETER; } -/******************************************************************** -********************************************************************/ - -static int32 DNSSendTCPRequest( HANDLE hDNSHandle, - uint8 * pDNSSendBuffer, - int32 dwBufferSize, int32 * pdwBytesSent ) +static DNS_ERROR write_all(int fd, uint8 *data, size_t len) { - int32 dwError = 0; - int32 dwBytesSent = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - + size_t total = 0; - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; + while (total < len) { - dwBytesSent = send( pDNSContext->s, pDNSSendBuffer, dwBufferSize, 0 ); - if ( dwBytesSent == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); - } - - *pdwBytesSent = dwBytesSent; - - return dwError; + ssize_t ret = write(fd, data + total, len - total); - error: - *pdwBytesSent = 0; - return dwError; -} - -/******************************************************************** -********************************************************************/ + if (ret <= 0) { + /* + * EOF or error + */ + return ERROR_DNS_SOCKET_ERROR; + } -static int32 DNSSendUDPRequest( HANDLE hDNSHandle, - uint8 * pDNSSendBuffer, - int32 dwBufferSize, int32 * pdwBytesSent ) -{ - int32 dwError = 0; - int32 dwBytesSent = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - - dwBytesSent = sendto( pDNSContext->s, - pDNSSendBuffer, - dwBufferSize, - 0, - ( struct sockaddr * ) & pDNSContext->RecvAddr, - sizeof( pDNSContext->RecvAddr ) - ); - if ( dwBytesSent == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); - } else { - *pdwBytesSent = dwBytesSent; + total += ret; } - return dwError; - - error: - *pdwBytesSent = 0; - return dwError; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -static int32 DNSSelect( HANDLE hDNSHandle ) +static DNS_ERROR dns_send_tcp(struct dns_connection *conn, + const struct dns_buffer *buf) { - int32 dwError = 0; - fd_set rfds; - struct timeval tv; - int32 dwNumSockets = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - FD_ZERO( &rfds ); - FD_SET( pDNSContext->s, &rfds ); - - tv.tv_sec = 10; - tv.tv_usec = 0; - dwNumSockets = select( pDNSContext->s + 1, &rfds, NULL, NULL, &tv ); - if ( dwNumSockets == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); - } - - if ( !dwNumSockets ) { -#ifndef WIN32 - dwError = ETIMEDOUT; -#else - dwError = WSAETIMEDOUT; -#endif - } + uint16 len = htons(buf->offset); + DNS_ERROR err; - error: + err = write_all(conn->s, (uint8 *)&len, sizeof(len)); + if (!ERR_DNS_IS_OK(err)) return err; - return dwError; + return write_all(conn->s, buf->data, buf->offset); } -/******************************************************************** -********************************************************************/ - -static int32 DNSTCPReceiveBufferContext( HANDLE hDNSHandle, - HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ) +static DNS_ERROR dns_send_udp(struct dns_connection *conn, + const struct dns_buffer *buf) { - int32 dwError = 0; - int32 dwRead = 0; - int16 wBytesToRead = 0; - int16 wnBytesToRead = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer; - - dwError = DNSSelect( hDNSHandle ); - BAIL_ON_ERROR( dwError ); - - dwRead = recv( pDNSContext->s, ( char * ) &wnBytesToRead, - sizeof( int16 ), 0 ); - if ( dwRead == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); - } - - wBytesToRead = ntohs( wnBytesToRead ); + ssize_t ret; - dwError = DNSSelect( hDNSHandle ); - BAIL_ON_ERROR( dwError ); + ret = sendto(conn->s, buf->data, buf->offset, 0, + (struct sockaddr *)&conn->RecvAddr, + sizeof(conn->RecvAddr)); - dwRead = recv( pDNSContext->s, - ( char * ) pDNSRecvContext->pRecvBuffer, wBytesToRead, - 0 ); - if ( dwRead == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); + if (ret != buf->offset) { + return ERROR_DNS_SOCKET_ERROR; } - pDNSRecvContext->dwBytesRecvd = dwRead; - - *pdwBytesRead = ( int32 ) dwRead; - - return dwError; - - error: - - return dwError; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -static int32 DNSUDPReceiveBufferContext( HANDLE hDNSHandle, - HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ) +DNS_ERROR dns_send(struct dns_connection *conn, const struct dns_buffer *buf) { - int32 dwError = 0; - int32 dwRead = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - DNS_RECEIVEBUFFER_CONTEXT *pDNSRecvContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - pDNSRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer; - - dwError = DNSSelect( hDNSHandle ); - BAIL_ON_ERROR( dwError ); - - dwRead = recv( pDNSContext->s, - ( char * ) pDNSRecvContext->pRecvBuffer, 512, 0 ); - if ( dwRead == SOCKET_ERROR ) { - dwError = WSAGetLastError( ); - BAIL_ON_ERROR( dwError ); + if (conn->hType == DNS_TCP) { + return dns_send_tcp(conn, buf); } - pDNSRecvContext->dwBytesRecvd = dwRead; - - *pdwBytesRead = ( int32 ) dwRead; - - error: - - return dwError; -} - -/******************************************************************** -********************************************************************/ - -int32 DNSReceiveBufferContext( HANDLE hDNSHandle, - HANDLE hDNSRecvBuffer, int32 * pdwBytesRead ) -{ - int32 dwError = 0; - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSHandle; - - switch ( pDNSContext->hType ) { - case DNS_TCP: - dwError = - DNSTCPReceiveBufferContext( hDNSHandle, - hDNSRecvBuffer, - pdwBytesRead ); - break; - case DNS_UDP: - dwError = - DNSUDPReceiveBufferContext( hDNSHandle, - hDNSRecvBuffer, - pdwBytesRead ); - break; + if (conn->hType == DNS_UDP) { + return dns_send_udp(conn, buf); } - return dwError; -} - -/******************************************************************** -********************************************************************/ - -int32 DNSCreateSendBuffer( HANDLE * phDNSSendBuffer ) -{ - int32 dwError = 0; - DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL; - uint8 *pSendBuffer = NULL; - - dwError = DNSAllocateMemory( sizeof( DNS_SENDBUFFER_CONTEXT ), - ( void * ) &pDNSContext ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( SENDBUFFER_SIZE, - ( void * ) &pSendBuffer ); - BAIL_ON_ERROR( dwError ); - - pDNSContext->pSendBuffer = pSendBuffer; - pDNSContext->dwBufferSize = SENDBUFFER_SIZE; - - /* We will offset into the buffer by 2 bytes - If we are doing a TCP write; we will fill in these - two bytes and send + 2 bytes - If we are doing a UDP write; we will start our send - +2 bytes and only send dwWritten; */ - - pDNSContext->dwBufferOffset += 2; - - *phDNSSendBuffer = ( HANDLE ) pDNSContext; - - return dwError; - error: - - if ( pSendBuffer ) { - DNSFreeMemory( pSendBuffer ); - } - if ( pDNSContext ) { - DNSFreeMemory( pDNSContext ); - } - *phDNSSendBuffer = ( HANDLE ) NULL; - - return dwError; + return ERROR_DNS_INVALID_PARAMETER; } - -/******************************************************************** -********************************************************************/ - -int32 DNSMarshallBuffer( HANDLE hDNSSendBuffer, - uint8 * pDNSSendBuffer, - int32 dwBufferSize, int32 * pdwBytesWritten ) +static DNS_ERROR read_all(int fd, uint8 *data, size_t len) { - int32 dwError = 0; - uint8 *pTemp = NULL; - DNS_SENDBUFFER_CONTEXT *pDNSContext = NULL; + size_t total = 0; -/* BugBug - we need to check for amount of space remaining in the -SendBuffer Context - if its insufficent, we want to realloc the -Buffer and copy the context; Right now the assumption is we have a big -enough buffer */ + while (total < len) { - pDNSContext = ( DNS_SENDBUFFER_CONTEXT * ) hDNSSendBuffer; + ssize_t ret = read(fd, data + total, len - total); - pTemp = pDNSContext->pSendBuffer + pDNSContext->dwBufferOffset; - - memcpy( pTemp, pDNSSendBuffer, dwBufferSize ); - - pDNSContext->dwBytesWritten += dwBufferSize; - pDNSContext->dwBufferOffset += dwBufferSize; + if (ret <= 0) { + /* + * EOF or error + */ + return ERROR_DNS_SOCKET_ERROR; + } - *pdwBytesWritten = dwBufferSize; + total += ret; + } - return dwError; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -static int32 DNSTCPSendBufferContext( HANDLE hDNSServer, - HANDLE hSendBuffer, int32 * pdwBytesSent ) +static DNS_ERROR dns_receive_tcp(TALLOC_CTX *mem_ctx, + struct dns_connection *conn, + struct dns_buffer **presult) { - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; - int32 dwError = 0; - int16 wBytesWritten = 0; - int16 wnBytesWritten = 0; - - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; - - wBytesWritten = ( int16 ) pSendBufferContext->dwBytesWritten; - wnBytesWritten = htons( wBytesWritten ); - - memcpy( pSendBufferContext->pSendBuffer, &wnBytesWritten, - sizeof( int16 ) ); - - dwError = DNSSendTCPRequest( hDNSServer, - pSendBufferContext->pSendBuffer, - pSendBufferContext->dwBytesWritten + 2, - pdwBytesSent ); - BAIL_ON_ERROR( dwError ); - - error: - - return dwError; -} + struct dns_buffer *buf; + DNS_ERROR err; + uint16 len; -/******************************************************************** -********************************************************************/ - -static int32 DNSUDPSendBufferContext( HANDLE hDNSServer, - HANDLE hSendBuffer, int32 * pdwBytesSent ) -{ - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; - int32 dwError = 0; + if (!(buf = TALLOC_ZERO_P(mem_ctx, struct dns_buffer))) { + return ERROR_DNS_NO_MEMORY; + } - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + err = read_all(conn->s, (uint8 *)&len, sizeof(len)); + if (!ERR_DNS_IS_OK(err)) { + return err; + } - /* Now remember to send 2 bytes ahead of pSendBuffer; because - we ignore the 2 bytes size field. */ + buf->size = ntohs(len); - dwError = DNSSendUDPRequest( hDNSServer, - pSendBufferContext->pSendBuffer + 2, - pSendBufferContext->dwBytesWritten, - pdwBytesSent ); - BAIL_ON_ERROR( dwError ); + if (!(buf->data = TALLOC_ARRAY(buf, uint8, buf->size))) { + TALLOC_FREE(buf); + return ERROR_DNS_NO_MEMORY; + } - error: + err = read_all(conn->s, buf->data, buf->size); + if (!ERR_DNS_IS_OK(err)) { + TALLOC_FREE(buf); + return err; + } - return dwError; + *presult = buf; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -int32 DNSSendBufferContext( HANDLE hDNSServer, - HANDLE hSendBuffer, int32 * pdwBytesSent ) +static DNS_ERROR dns_receive_udp(TALLOC_CTX *mem_ctx, + struct dns_connection *conn, + struct dns_buffer **presult) { - DNS_CONNECTION_CONTEXT *pDNSContext = NULL; - int32 dwError = 0; - - pDNSContext = ( DNS_CONNECTION_CONTEXT * ) hDNSServer; - - switch ( pDNSContext->hType ) { - case DNS_TCP: - dwError = DNSTCPSendBufferContext( hDNSServer, - hSendBuffer, - pdwBytesSent ); - BAIL_ON_ERROR( dwError ); - break; + struct dns_buffer *buf; + ssize_t received; - case DNS_UDP: - dwError = DNSUDPSendBufferContext( hDNSServer, - hSendBuffer, - pdwBytesSent ); - BAIL_ON_ERROR( dwError ); - break; + if (!(buf = TALLOC_ZERO_P(mem_ctx, struct dns_buffer))) { + return ERROR_DNS_NO_MEMORY; } - error: - return dwError; -} - -/******************************************************************** -********************************************************************/ + /* + * UDP based DNS can only be 512 bytes + */ -int32 DNSDumpSendBufferContext( HANDLE hSendBuffer ) -{ - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; - int32 dwError = 0; - int32 dwCurLine = 0; - int32 i = 0; - - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; - printf( "\n" ); - printf( "Buffer Size is: %d\n", pSendBufferContext->dwBytesWritten ); - while ( i < pSendBufferContext->dwBytesWritten ) { - if ( ( i / 16 ) > dwCurLine ) { - printf( "\n" ); - dwCurLine++; - } - if ( ( i % 8 ) == 0 ) { - printf( " " ); - } - printf( "%.2x ", pSendBufferContext->pSendBuffer[i] ); - i++; + if (!(buf->data = TALLOC_ARRAY(buf, uint8, 512))) { + TALLOC_FREE(buf); + return ERROR_DNS_NO_MEMORY; } - return dwError; -} - -/******************************************************************** -********************************************************************/ -int32 DNSDumpRecvBufferContext( HANDLE hRecvBuffer ) -{ - DNS_RECEIVEBUFFER_CONTEXT *pRecvBufferContext = NULL; - int32 dwError = 0; - int32 dwCurLine = 0; - int32 i = 0; - - pRecvBufferContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer; - - printf( "\n" ); - printf( "Buffer Size is: %d\n", pRecvBufferContext->dwBytesRecvd ); + received = recv(conn->s, (void *)buf->data, 512, 0); - while ( i < pRecvBufferContext->dwBytesRecvd ) { - if ( ( i / 16 ) > dwCurLine ) { - printf( "\n" ); - dwCurLine++; - } - if ( ( i % 8 ) == 0 ) { - printf( " " ); - } - printf( "%.2x ", pRecvBufferContext->pRecvBuffer[i] ); - i++; + if (received == -1) { + TALLOC_FREE(buf); + return ERROR_DNS_SOCKET_ERROR; } - return dwError; -} -/******************************************************************** -********************************************************************/ - -int32 DNSCreateReceiveBuffer( HANDLE * phDNSRecvBuffer ) -{ - int32 dwError = 0; - DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL; - uint8 *pRecvBuffer = NULL; - - dwError = DNSAllocateMemory( sizeof( DNS_RECEIVEBUFFER_CONTEXT ), - ( void * ) &pDNSContext ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( RECVBUFFER_SIZE, - ( void * ) &pRecvBuffer ); - BAIL_ON_ERROR( dwError ); - - pDNSContext->pRecvBuffer = pRecvBuffer; - pDNSContext->dwBufferSize = RECVBUFFER_SIZE; - - *phDNSRecvBuffer = ( HANDLE ) pDNSContext; - - return dwError; - - error: - - if ( pRecvBuffer ) { - DNSFreeMemory( pRecvBuffer ); - } - if ( pDNSContext ) { - DNSFreeMemory( pDNSContext ); + if (received > 512) { + TALLOC_FREE(buf); + return ERROR_DNS_BAD_RESPONSE; } - *phDNSRecvBuffer = ( HANDLE ) NULL; - return dwError; -} - -/******************************************************************** -********************************************************************/ - -int32 DNSUnmarshallBuffer( HANDLE hDNSRecvBuffer, - uint8 * pDNSRecvBuffer, - int32 dwBufferSize, int32 * pdwBytesRead ) -{ - int32 dwError = 0; - uint8 *pTemp = NULL; - DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL; - -/* BugBug - we need to check for amount of space remaining in the -SendBuffer Context - if its insufficent, we want to realloc the -Buffer and copy the context; Right now the assumption is we have a big -enough buffer */ - - pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hDNSRecvBuffer; - - pTemp = pDNSContext->pRecvBuffer + pDNSContext->dwBytesRead; - - memcpy( pDNSRecvBuffer, pTemp, dwBufferSize ); - - pDNSContext->dwBytesRead += dwBufferSize; - - *pdwBytesRead = dwBufferSize; + buf->size = received; + buf->offset = 0; - return dwError; + *presult = buf; + return ERROR_DNS_SUCCESS; } -/******************************************************************** -********************************************************************/ - -int32 DNSUnmarshallDomainNameAtOffset( HANDLE hRecvBuffer, - int16 wOffset, - DNS_DOMAIN_NAME ** ppDomainName ) +DNS_ERROR dns_receive(TALLOC_CTX *mem_ctx, struct dns_connection *conn, + struct dns_buffer **presult) { - int32 dwError = 0; - DNS_DOMAIN_LABEL *pLabel = NULL; - DNS_DOMAIN_LABEL *pLabelList = NULL; - DNS_DOMAIN_NAME *pDomainName = NULL; - char *pszLabel = NULL; - char szLabel[65]; - uint8 uLen = 0; - int32 dwCurrent = 0; - DNS_RECEIVEBUFFER_CONTEXT *pRecvContext = NULL; - - pRecvContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer; - dwCurrent = wOffset; - - while ( 1 ) { - - memcpy( &uLen, pRecvContext->pRecvBuffer + dwCurrent, - sizeof( char ) ); - dwCurrent++; - - if ( uLen == 0 ) { - break; - } - - memset( szLabel, 0, 65 ); - memcpy( szLabel, pRecvContext->pRecvBuffer + dwCurrent, - uLen ); - dwCurrent += uLen; - - dwError = DNSAllocateString( szLabel, &pszLabel ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_DOMAIN_LABEL ), - ( void * ) &pLabel ); - BAIL_ON_ERROR( dwError ); - - pLabel->pszLabel = pszLabel; - dwError = DNSAppendLabel( pLabelList, pLabel, &pLabelList ); - BAIL_ON_ERROR( dwError ); + if (conn->hType == DNS_TCP) { + return dns_receive_tcp(mem_ctx, conn, presult); } - dwError = - DNSAllocateMemory( sizeof( DNS_DOMAIN_NAME ), - ( void * ) &pDomainName ); - BAIL_ON_ERROR( dwError ); - pDomainName->pLabelList = pLabelList; - - *ppDomainName = pDomainName; - - return dwError; - - error: + if (conn->hType == DNS_UDP) { + return dns_receive_udp(mem_ctx, conn, presult); + } - *ppDomainName = NULL; - return dwError; + return ERROR_DNS_INVALID_PARAMETER; } -/******************************************************************** -********************************************************************/ - -int32 DNSReceiveBufferMoveBackIndex( HANDLE hRecvBuffer, int16 wOffset ) +DNS_ERROR dns_transaction(TALLOC_CTX *mem_ctx, struct dns_connection *conn, + const struct dns_request *req, + struct dns_request **resp) { - int32 dwError = 0; - DNS_RECEIVEBUFFER_CONTEXT *pDNSContext = NULL; - - pDNSContext = ( DNS_RECEIVEBUFFER_CONTEXT * ) hRecvBuffer; - pDNSContext->dwBytesRead -= wOffset; + struct dns_buffer *buf = NULL; + DNS_ERROR err; - return dwError; -} + err = dns_marshall_request(conn, req, &buf); + if (!ERR_DNS_IS_OK(err)) goto error; -/******************************************************************** -********************************************************************/ + err = dns_send(conn, buf); + if (!ERR_DNS_IS_OK(err)) goto error; + TALLOC_FREE(buf); -void DNSFreeSendBufferContext( HANDLE hSendBuffer ) -{ - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + err = dns_receive(mem_ctx, conn, &buf); + if (!ERR_DNS_IS_OK(err)) goto error; - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + err = dns_unmarshall_request(mem_ctx, buf, resp); - if ( pSendBufferContext && pSendBufferContext->pSendBuffer ) { - DNSFreeMemory( pSendBufferContext->pSendBuffer ); - } - if ( pSendBufferContext ) { - DNSFreeMemory( pSendBufferContext ); - } + error: + TALLOC_FREE(buf); + return err; } -/******************************************************************** -********************************************************************/ - -int32 DNSGetSendBufferContextSize( HANDLE hSendBuffer ) +DNS_ERROR dns_update_transaction(TALLOC_CTX *mem_ctx, + struct dns_connection *conn, + struct dns_update_request *up_req, + struct dns_update_request **up_resp) { - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; + struct dns_request *resp; + DNS_ERROR err; - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; + err = dns_transaction(mem_ctx, conn, dns_update2request(up_req), + &resp); - return ( pSendBufferContext->dwBytesWritten ); + if (!ERR_DNS_IS_OK(err)) return err; + *up_resp = dns_request2update(resp); + return ERROR_DNS_SUCCESS; } - -/******************************************************************** -********************************************************************/ - -uint8 *DNSGetSendBufferContextBuffer( HANDLE hSendBuffer ) -{ - DNS_SENDBUFFER_CONTEXT *pSendBufferContext = NULL; - - pSendBufferContext = ( DNS_SENDBUFFER_CONTEXT * ) hSendBuffer; - - return ( pSendBufferContext->pSendBuffer ); -} - diff --git a/source3/libaddns/dnsupdate.c b/source3/libaddns/dnsupdate.c deleted file mode 100644 index 124b627707..0000000000 --- a/source3/libaddns/dnsupdate.c +++ /dev/null @@ -1,644 +0,0 @@ -/* - Public Interface file for 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" - -/******************************************************************** -********************************************************************/ - -static int32 DNSSendUpdate1( HANDLE hDNSServer, const char *szDomainName, - char *szHost, struct in_addr *iplist, - int num_ips, - DNS_UPDATE_RESPONSE * *ppDNSUpdateResponse ) -{ - int32 dwError = 0; - DNS_UPDATE_REQUEST *pDNSUpdateRequest = NULL; - DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL; - DNS_ZONE_RECORD *pDNSZoneRecord = NULL; - DNS_RR_RECORD *pDNSPRRecord = NULL; - int i; - - dwError = DNSUpdateCreateUpdateRequest( &pDNSUpdateRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateZoneRecord( szDomainName, &pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateAddZoneSection( pDNSUpdateRequest, pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); - - /* Add the CNAME not in user record */ - - pDNSPRRecord = NULL; - dwError = - DNSCreateNameNotInUseRecord( szHost, QTYPE_CNAME, - &pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - /* Add a Prerequisite for each IP address to see if everything is already setup */ - - for ( i = 0; i < num_ips; i++ ) { - DNS_RR_RECORD *pDNSPrereq = NULL; - - dwError = - DNSCreateNameInUseRecord( szHost, QTYPE_A, &iplist[i], - &pDNSPrereq ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateAddPRSection( pDNSUpdateRequest, - pDNSPrereq ); - BAIL_ON_ERROR( dwError ); - } - - dwError = - DNSUpdateSendUpdateRequest2( hDNSServer, pDNSUpdateRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateReceiveUpdateResponse( hDNSServer, - &pDNSUpdateResponse ); - BAIL_ON_ERROR( dwError ); - - *ppDNSUpdateResponse = pDNSUpdateResponse; - - return dwError; - - error: - - if ( pDNSZoneRecord ) { - DNSFreeZoneRecord( pDNSZoneRecord ); - } - - if ( pDNSUpdateRequest ) { - DNSUpdateFreeRequest( pDNSUpdateRequest ); - } - - *ppDNSUpdateResponse = NULL; - return dwError; -} - -/******************************************************************** -********************************************************************/ - -static int32 DNSSendUpdate2( HANDLE hDNSServer, const char *szDomainName, - char *szHost, struct in_addr *iplist, - int num_ips, - DNS_UPDATE_RESPONSE * *ppDNSUpdateResponse ) -{ - int32 dwError = 0; - DNS_UPDATE_REQUEST *pDNSUpdateRequest = NULL; - DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL; - DNS_ZONE_RECORD *pDNSZoneRecord = NULL; - DNS_RR_RECORD *pDNSPRRecord = NULL; - int i; - - dwError = DNSUpdateCreateUpdateRequest( &pDNSUpdateRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateZoneRecord( szDomainName, &pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateAddZoneSection( pDNSUpdateRequest, pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); - - /* Add the CNAME not in user record */ - - pDNSPRRecord = NULL; - dwError = - DNSCreateNameNotInUseRecord( szHost, QTYPE_CNAME, - &pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - /* Add the IN not in user record */ - - pDNSPRRecord = NULL; - dwError = - DNSCreateNameNotInUseRecord( szHost, QTYPE_A, &pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - - for ( i = 0; i < num_ips; i++ ) { - DNS_RR_RECORD *pDNSRRAddRecord = NULL; - - dwError = - DNSCreateARecord( szHost, DNS_CLASS_IN, QTYPE_A, - ntohl( iplist[i].s_addr ), - &pDNSRRAddRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateAddUpdateSection( pDNSUpdateRequest, - pDNSRRAddRecord ); - BAIL_ON_ERROR( dwError ); - } - - dwError = - DNSUpdateSendUpdateRequest2( hDNSServer, pDNSUpdateRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateReceiveUpdateResponse( hDNSServer, - &pDNSUpdateResponse ); - BAIL_ON_ERROR( dwError ); - - *ppDNSUpdateResponse = pDNSUpdateResponse; - - return dwError; - - error: - - if ( pDNSZoneRecord ) { - DNSFreeZoneRecord( pDNSZoneRecord ); - } - - if ( pDNSUpdateRequest ) { - DNSUpdateFreeRequest( pDNSUpdateRequest ); - } - - *ppDNSUpdateResponse = NULL; - return dwError; -} - -/******************************************************************** -********************************************************************/ - -static int32 DNSSendUpdate3( HANDLE hDNSServer, const char *szDomainName, - char *szHost, struct in_addr *iplist, - int num_ips, - DNS_UPDATE_RESPONSE * *ppDNSUpdateResponse ) -{ - int32 dwError = 0; - DNS_UPDATE_REQUEST *pDNSUpdateRequest = NULL; - DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL; - DNS_ZONE_RECORD *pDNSZoneRecord = NULL; - DNS_RR_RECORD *pDNSPRRecord = NULL; - int i; - DNS_RR_RECORD *pDNSRRAddRecord = NULL; - - dwError = DNSUpdateCreateUpdateRequest( &pDNSUpdateRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateZoneRecord( szDomainName, &pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateAddZoneSection( pDNSUpdateRequest, pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); - - /* Add the CNAME not in user record */ - - dwError = - DNSCreateNameNotInUseRecord( szHost, QTYPE_CNAME, - &pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - /* Delete any existing A records */ - - dwError = - DNSCreateARecord( szHost, DNS_CLASS_ANY, QTYPE_A, 0, - &pDNSRRAddRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateAddUpdateSection( pDNSUpdateRequest, - pDNSRRAddRecord ); - BAIL_ON_ERROR( dwError ); - - - for ( i = 0; i < num_ips; i++ ) { - - dwError = - DNSCreateARecord( szHost, DNS_CLASS_IN, QTYPE_A, - ntohl( iplist[i].s_addr ), - &pDNSRRAddRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateAddUpdateSection( pDNSUpdateRequest, - pDNSRRAddRecord ); - BAIL_ON_ERROR( dwError ); - } - - dwError = - DNSUpdateSendUpdateRequest2( hDNSServer, pDNSUpdateRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateReceiveUpdateResponse( hDNSServer, - &pDNSUpdateResponse ); - BAIL_ON_ERROR( dwError ); - - *ppDNSUpdateResponse = pDNSUpdateResponse; - - return dwError; - - error: - - if ( pDNSZoneRecord ) { - DNSFreeZoneRecord( pDNSZoneRecord ); - } - - if ( pDNSUpdateRequest ) { - DNSUpdateFreeRequest( pDNSUpdateRequest ); - } - - *ppDNSUpdateResponse = NULL; - - return dwError; -} - -/******************************************************************** -********************************************************************/ - -int32 DNSSendUpdate( HANDLE hDNSServer, const char *szDomainName, char *szHost, - struct in_addr * iplist, int num_ips, - DNS_UPDATE_RESPONSE * *ppDNSUpdateResponse ) -{ - int32 dwError = 0; - int32 dwResponseCode = 0; - DNS_UPDATE_RESPONSE *response = NULL; - - dwError = DNSSendUpdate1( hDNSServer, szDomainName, szHost, - iplist, num_ips, &response ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateGetResponseCode( response, &dwResponseCode ); - BAIL_ON_ERROR( dwError ); - - if ( ( dwResponseCode == DNS_NO_ERROR ) - || ( dwResponseCode == DNS_REFUSED ) ) { - *ppDNSUpdateResponse = response; - return dwError; - } - - response = NULL; - - dwError = DNSSendUpdate2( hDNSServer, szDomainName, szHost, - iplist, num_ips, &response ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateGetResponseCode( response, &dwResponseCode ); - BAIL_ON_ERROR( dwError ); - - if ( ( dwResponseCode == DNS_NO_ERROR ) - || ( dwResponseCode == DNS_REFUSED ) ) { - *ppDNSUpdateResponse = response; - return dwError; - } - - response = NULL; - - dwError = DNSSendUpdate3( hDNSServer, szDomainName, szHost, - iplist, num_ips, &response ); - - error: - *ppDNSUpdateResponse = response; - - return dwError; -} - -/******************************************************************** -********************************************************************/ -#ifdef HAVE_GSSAPI_SUPPORT -int32 DNSSendSecureUpdate( HANDLE hDNSServer, - gss_ctx_id_t * pGSSContext, - char *pszKeyName, - char *szDomainName, - char *szHost, - int32 dwIP, DNS_UPDATE_RESPONSE ** ppDNSUpdateResponse ) -{ - int32 dwError = 0; - DNS_UPDATE_REQUEST *pDNSUpdateRequest = NULL; - DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL; - DNS_ZONE_RECORD *pDNSZoneRecord = NULL; - DNS_RR_RECORD *pDNSPRRecord = NULL; - DNS_RR_RECORD *pDNSARecord = NULL; - - - dwError = DNSUpdateCreateUpdateRequest( &pDNSUpdateRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateZoneRecord( szDomainName, &pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateAddZoneSection( pDNSUpdateRequest, - pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateNameInUseRecord( szDomainName, - QTYPE_A, NULL, &pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateAddPRSection( pDNSUpdateRequest, pDNSPRRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateDeleteRecord( szHost, - DNS_CLASS_ANY, - QTYPE_A, &pDNSARecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateAddUpdateSection( pDNSUpdateRequest, pDNSARecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateARecord( szHost, - DNS_CLASS_IN, - QTYPE_A, dwIP, &pDNSARecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateAddUpdateSection( pDNSUpdateRequest, pDNSARecord ); - BAIL_ON_ERROR( dwError ); - - /* Now Sign the Record */ - - dwError = DNSUpdateGenerateSignature( pGSSContext, - pDNSUpdateRequest, pszKeyName ); - BAIL_ON_ERROR( dwError ); - - - dwError = - DNSUpdateSendUpdateRequest2( hDNSServer, pDNSUpdateRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateReceiveUpdateResponse( hDNSServer, - &pDNSUpdateResponse ); - BAIL_ON_ERROR( dwError ); - - *ppDNSUpdateResponse = pDNSUpdateResponse; - - return dwError; - - error: - - if ( pDNSZoneRecord ) { - DNSFreeZoneRecord( pDNSZoneRecord ); - } - - if ( pDNSUpdateRequest ) { - DNSUpdateFreeRequest( pDNSUpdateRequest ); - } - - *ppDNSUpdateResponse = NULL; - - return dwError; -} - - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateGenerateSignature( gss_ctx_id_t * pGSSContext, - DNS_UPDATE_REQUEST * pDNSUpdateRequest, - char *pszKeyName ) -{ - int32 dwError = 0; - int32 dwMinorStatus = 0; - uint8 *pMessageBuffer = NULL; - int32 dwMessageSize = 0; - int32 dwMaxSignatureSize = 0; - uint8 *pSignature = NULL; - int32 dwTimeSigned = 0; - int16 wFudge = 0; - gss_buffer_desc MsgDesc, MicDesc; - DNS_RR_RECORD *pDNSTSIGRecord = NULL; - - dwError = DNSBuildMessageBuffer( pDNSUpdateRequest, - pszKeyName, - &dwTimeSigned, - &wFudge, - &pMessageBuffer, &dwMessageSize ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSBuildSignatureBuffer( dwMaxSignatureSize, &pSignature ); - BAIL_ON_ERROR( dwError ); - - MsgDesc.value = pMessageBuffer; - MsgDesc.length = dwMessageSize; - - MicDesc.value = NULL; - MicDesc.length = 0; - - dwError = gss_get_mic( ( OM_uint32 * ) & dwMinorStatus, - *pGSSContext, 0, &MsgDesc, &MicDesc ); - display_status( "gss_init_context", dwError, dwMinorStatus ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSCreateTSIGRecord( pszKeyName, - dwTimeSigned, - wFudge, - pDNSUpdateRequest->wIdentification, - (uint8 *)MicDesc.value, - MicDesc.length, &pDNSTSIGRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSUpdateAddAdditionalSection( pDNSUpdateRequest, - pDNSTSIGRecord ); - BAIL_ON_ERROR( dwError ); - - - error: - - if ( pMessageBuffer ) { - DNSFreeMemory( pMessageBuffer ); - } - return dwError; - - if ( pSignature ) { - DNSFreeMemory( pSignature ); - } - - return dwError; -} -#endif /* HAVE_GSSAPI_SUPPORT */ - -/********************************************************************* -*********************************************************************/ - -int32 DNSBuildSignatureBuffer( int32 dwMaxSignatureSize, uint8 ** ppSignature ) -{ - int32 dwError = 0; - uint8 *pSignature = NULL; - - dwError = DNSAllocateMemory( dwMaxSignatureSize, - ( void * ) &pSignature ); - BAIL_ON_ERROR( dwError ); - - *ppSignature = pSignature; - - return dwError; - - error: - *ppSignature = NULL; - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSBuildMessageBuffer( DNS_UPDATE_REQUEST * pDNSUpdateRequest, - char *szKeyName, - int32 * pdwTimeSigned, - int16 * pwFudge, - uint8 ** ppMessageBuffer, int32 * pdwMessageSize ) -{ - int32 dwError = 0; - uint8 *pSrcBuffer = NULL; - int32 dwReqMsgSize = 0; - int32 dwAlgorithmLen = 0; - int32 dwNameLen = 0; - uint8 *pMessageBuffer = NULL; - int32 dwMessageSize = 0; - uint8 *pOffset = NULL; - int16 wnError, wError = 0; - int16 wnFudge = 0; - int16 wFudge = DNS_TEN_HOURS_IN_SECS; - int16 wnOtherLen = 0, wOtherLen = 0; - int32 dwBytesCopied = 0; - int16 wnClass = 0, wClass = DNS_CLASS_ANY; - int32 dwnTTL = 0, dwTTL = 0; - int32 dwnTimeSigned, dwTimeSigned = 0; - HANDLE hSendBuffer = ( HANDLE ) NULL; - DNS_DOMAIN_NAME *pDomainName = NULL; - DNS_DOMAIN_NAME *pAlgorithmName = NULL; - int16 wTimePrefix = 0; - int16 wnTimePrefix = 0; - char szTsig[9]; - - dwError = DNSDomainNameFromString( szKeyName, &pDomainName ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSGetDomainNameLength( pDomainName, &dwNameLen ); - BAIL_ON_ERROR( dwError ); - - strncpy( szTsig, "gss-tsig", sizeof( szTsig ) ); - dwError = DNSDomainNameFromString( szTsig, &pAlgorithmName ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSGetDomainNameLength( pAlgorithmName, &dwAlgorithmLen ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUpdateBuildRequestMessage( pDNSUpdateRequest, - &hSendBuffer ); - BAIL_ON_ERROR( dwError ); - - dwReqMsgSize = DNSGetSendBufferContextSize( hSendBuffer ); - dwMessageSize += dwReqMsgSize; - dwMessageSize += dwNameLen; - dwMessageSize += sizeof( int16 ); /* class */ - dwMessageSize += sizeof( int32 ); /* TTL */ - dwMessageSize += dwAlgorithmLen; - dwMessageSize += ( sizeof( int16 ) + sizeof( int32 ) ); /* Time Signed */ - dwMessageSize += sizeof( int16 ); /* Fudge */ - dwMessageSize += sizeof( int16 ); /* wError */ - dwMessageSize += sizeof( int16 ); /* Other Len */ - dwMessageSize += wOtherLen; - - dwError = - DNSAllocateMemory( dwMessageSize, - ( void * ) &pMessageBuffer ); - BAIL_ON_ERROR( dwError ); - - pOffset = pMessageBuffer; - pSrcBuffer = DNSGetSendBufferContextBuffer( hSendBuffer ); - memcpy( pOffset, pSrcBuffer, dwReqMsgSize ); - pOffset += dwReqMsgSize; - - dwError = - DNSCopyDomainName( pOffset, pAlgorithmName, &dwBytesCopied ); - BAIL_ON_ERROR( dwError ); - pOffset += dwBytesCopied; - - wnClass = htons( wClass ); - memcpy( pOffset, &wnClass, sizeof( int16 ) ); - pOffset += sizeof( int16 ); - - dwnTTL = htonl( dwTTL ); - memcpy( pOffset, &dwnTTL, sizeof( int32 ) ); - pOffset += sizeof( int32 ); - - - wnTimePrefix = htons( wTimePrefix ); - memcpy( pOffset, &wnTimePrefix, sizeof( int16 ) ); - pOffset += sizeof( int16 ); - - { - time_t t; - time(&t); - dwTimeSigned = t; - } - dwnTimeSigned = htonl( dwTimeSigned ); - memcpy( pOffset, &dwnTimeSigned, sizeof( int32 ) ); - pOffset += sizeof( int32 ); - - wnFudge = htons( wFudge ); - memcpy( pOffset, &wnFudge, sizeof( int16 ) ); - pOffset += sizeof( int16 ); - - wnError = htons( wError ); - memcpy( pOffset, &wnError, sizeof( int16 ) ); - pOffset += sizeof( int16 ); - - wnOtherLen = htons( wOtherLen ); - memcpy( pOffset, &wnOtherLen, sizeof( int16 ) ); - pOffset += sizeof( int16 ); - - *ppMessageBuffer = pMessageBuffer; - *pdwMessageSize = dwMessageSize; - - *pdwTimeSigned = dwTimeSigned; - *pwFudge = wFudge; - - return dwError; - - error: - - if ( pMessageBuffer ) { - DNSFreeMemory( pMessageBuffer ); - } - - *ppMessageBuffer = NULL; - *pdwMessageSize = 0; - *pdwTimeSigned = dwTimeSigned; - *pwFudge = wFudge; - return dwError; - -} diff --git a/source3/libaddns/dnsuprequest.c b/source3/libaddns/dnsuprequest.c deleted file mode 100644 index 9de5ec88ae..0000000000 --- a/source3/libaddns/dnsuprequest.c +++ /dev/null @@ -1,428 +0,0 @@ -/* - 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" - -/********************************************************************* -*********************************************************************/ - -static int32 DNSUpdateMarshallZoneSection( HANDLE hSendBuffer, - DNS_ZONE_RECORD ** ppDNSZoneRecords, - int16 wZones ) -{ - int32 dwError = 0; - int32 i = 0; - int32 dwRead = 0; - DNS_ZONE_RECORD *pDNSZoneRecord = NULL; - int16 wnZoneType = 0; - int16 wnZoneClass = 0; - - for ( i = 0; i < wZones; i++ ) { - - pDNSZoneRecord = *( ppDNSZoneRecords + i ); - dwError = - DNSMarshallDomainName( hSendBuffer, - pDNSZoneRecord->pDomainName ); - BAIL_ON_ERROR( dwError ); - - wnZoneType = htons( pDNSZoneRecord->wZoneType ); - dwError = - DNSMarshallBuffer( hSendBuffer, - ( uint8 * ) & wnZoneType, - ( int32 ) sizeof( int16 ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - - wnZoneClass = htons( pDNSZoneRecord->wZoneClass ); - dwError = - DNSMarshallBuffer( hSendBuffer, - ( uint8 * ) & wnZoneClass, - ( int32 ) sizeof( int16 ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - - pDNSZoneRecord++; - } - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSUpdateMarshallPRSection( HANDLE hSendBuffer, - DNS_RR_RECORD ** ppDNSPRRRRecords, int16 wPRs ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSPRRRRecord = NULL; - - - for ( i = 0; i < wPRs; i++ ) { - - pDNSPRRRRecord = *( ppDNSPRRRRecords + i ); - - dwError = DNSMarshallRRHeader( hSendBuffer, pDNSPRRRRecord ); - BAIL_ON_ERROR( dwError ); - - if ( pDNSPRRRRecord->RRHeader.wRDataSize ) { - dwError = - DNSMarshallRData( hSendBuffer, - pDNSPRRRRecord ); - BAIL_ON_ERROR( dwError ); - } - } - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSUpdateMarshallUpdateSection( HANDLE hSendBuffer, - DNS_RR_RECORD ** ppDNSUpdateRRRecords, - int16 wZones ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSUpdateRRRecord = NULL; - - for ( i = 0; i < wZones; i++ ) { - - pDNSUpdateRRRecord = *( ppDNSUpdateRRRecords + i ); - - dwError = - DNSMarshallRRHeader( hSendBuffer, - pDNSUpdateRRRecord ); - - if ( pDNSUpdateRRRecord->RRHeader.wRDataSize ) { - dwError = DNSMarshallRData( hSendBuffer, - pDNSUpdateRRRecord ); - BAIL_ON_ERROR( dwError ); - } - - } - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSUpdateMarshallAdditionalSection( HANDLE hSendBuffer, - DNS_RR_RECORD ** - ppDNSAdditionalsRRRecords, - int16 wAdditionals ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSAdditionalRRRecord = NULL; - - for ( i = 0; i < wAdditionals; i++ ) { - - pDNSAdditionalRRRecord = *( ppDNSAdditionalsRRRecords + i ); - - dwError = - DNSMarshallRRHeader( hSendBuffer, - pDNSAdditionalRRRecord ); - BAIL_ON_ERROR( dwError ); - - if ( pDNSAdditionalRRRecord->RRHeader.wRDataSize ) { - dwError = DNSMarshallRData( hSendBuffer, - pDNSAdditionalRRRecord ); - BAIL_ON_ERROR( dwError ); - } - } - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateSendUpdateRequest2( HANDLE hDNSServer, - DNS_UPDATE_REQUEST * pDNSRequest ) -{ - int32 dwError = 0; - int32 dwBytesSent = 0; - HANDLE hSendBuffer = ( HANDLE ) NULL; - - dwError = DNSUpdateBuildRequestMessage( pDNSRequest, &hSendBuffer ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSSendBufferContext( hDNSServer, hSendBuffer, &dwBytesSent ); - BAIL_ON_ERROR( dwError ); - - error: - - if ( hSendBuffer ) { - DNSFreeSendBufferContext( hSendBuffer ); - } - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateBuildRequestMessage( DNS_UPDATE_REQUEST * pDNSRequest, - HANDLE * phSendBuffer ) -{ - int32 dwError = 0; - char DNSMessageHeader[12]; - int16 wnIdentification = 0; - int16 wnParameter = 0; - int16 wnZones = 0; - int16 wnPRs = 0; - int16 wnUpdates = 0; - int16 wnAdditionals = 0; - int32 dwRead = 0; - HANDLE hSendBuffer = ( HANDLE ) NULL; - - dwError = DNSCreateSendBuffer( &hSendBuffer ); - BAIL_ON_ERROR( dwError ); - - wnIdentification = htons( pDNSRequest->wIdentification ); - memcpy( DNSMessageHeader, ( char * ) &wnIdentification, 2 ); - - wnParameter = htons( pDNSRequest->wParameter ); - memcpy( DNSMessageHeader + 2, ( char * ) &wnParameter, 2 ); - - wnZones = htons( pDNSRequest->wZones ); - memcpy( DNSMessageHeader + 4, ( char * ) &wnZones, 2 ); - - wnPRs = htons( pDNSRequest->wPRs ); - memcpy( DNSMessageHeader + 6, ( char * ) &wnPRs, 2 ); - - wnUpdates = htons( pDNSRequest->wUpdates ); - memcpy( DNSMessageHeader + 8, ( char * ) &wnUpdates, 2 ); - - wnAdditionals = htons( pDNSRequest->wAdditionals ); - memcpy( DNSMessageHeader + 10, ( char * ) &wnAdditionals, 2 ); - - dwError = - DNSMarshallBuffer( hSendBuffer, ( uint8 * ) DNSMessageHeader, - 12, &dwRead ); - BAIL_ON_ERROR( dwError ); - - if ( pDNSRequest->wZones ) { - dwError = - DNSUpdateMarshallZoneSection( hSendBuffer, - pDNSRequest-> - ppZoneRRSet, - pDNSRequest->wZones ); - BAIL_ON_ERROR( dwError ); - } - - if ( pDNSRequest->wPRs ) { - dwError = - DNSUpdateMarshallPRSection( hSendBuffer, - pDNSRequest->ppPRRRSet, - pDNSRequest->wPRs ); - BAIL_ON_ERROR( dwError ); - } - - if ( pDNSRequest->wUpdates ) { - dwError = - DNSUpdateMarshallUpdateSection( hSendBuffer, - pDNSRequest-> - ppUpdateRRSet, - pDNSRequest-> - wUpdates ); - BAIL_ON_ERROR( dwError ); - } - - if ( pDNSRequest->wAdditionals ) { - dwError = - DNSUpdateMarshallAdditionalSection( hSendBuffer, - pDNSRequest-> - ppAdditionalRRSet, - pDNSRequest-> - wAdditionals ); - BAIL_ON_ERROR( dwError ); - } -#if 0 - DNSDumpSendBufferContext( hSendBuffer ); -#endif - - *phSendBuffer = hSendBuffer; - - return dwError; - - error: - - if ( hSendBuffer ) { - DNSFreeSendBufferContext( hSendBuffer ); - } - - *phSendBuffer = ( HANDLE ) NULL; - return dwError; -} - - -/********************************************************************* -*********************************************************************/ - -void DNSUpdateFreeRequest( DNS_UPDATE_REQUEST * pDNSRequest ) -{ - return; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateAddZoneSection( DNS_UPDATE_REQUEST * pDNSRequest, - DNS_ZONE_RECORD * pDNSZone ) -{ - int32 dwNumZones = 0; - int32 dwError = 0; - - dwNumZones = pDNSRequest->wZones; - - dwError = DNSReallocMemory( ( uint8 * ) pDNSRequest->ppZoneRRSet, - ( void * ) &pDNSRequest->ppZoneRRSet, - ( dwNumZones + - 1 ) * sizeof( DNS_ZONE_RECORD * ) - ); - BAIL_ON_ERROR( dwError ); - - *( pDNSRequest->ppZoneRRSet + dwNumZones ) = pDNSZone; - - pDNSRequest->wZones += 1; - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateAddAdditionalSection( DNS_UPDATE_REQUEST * pDNSRequest, - DNS_RR_RECORD * pDNSRecord ) -{ - int32 dwNumAdditionals = 0; - int32 dwError = 0; - - dwNumAdditionals = pDNSRequest->wAdditionals; - dwError = DNSReallocMemory( pDNSRequest->ppAdditionalRRSet, - ( void * ) &pDNSRequest-> - ppAdditionalRRSet, - ( dwNumAdditionals + - 1 ) * sizeof( DNS_RR_RECORD * ) ); - BAIL_ON_ERROR( dwError ); - - *( pDNSRequest->ppAdditionalRRSet + dwNumAdditionals ) = pDNSRecord; - - pDNSRequest->wAdditionals += 1; - - error: - return dwError; -} - -int32 DNSUpdateAddPRSection( DNS_UPDATE_REQUEST * pDNSRequest, - DNS_RR_RECORD * pDNSRecord ) -{ - int32 dwNumPRs = 0; - int32 dwError = 0; - - dwNumPRs = pDNSRequest->wPRs; - dwError = DNSReallocMemory( pDNSRequest->ppPRRRSet, - ( void * ) &pDNSRequest->ppPRRRSet, - ( dwNumPRs + - 1 ) * sizeof( DNS_RR_RECORD * ) ); - BAIL_ON_ERROR( dwError ); - - *( pDNSRequest->ppPRRRSet + dwNumPRs ) = pDNSRecord; - - pDNSRequest->wPRs += 1; - - error: - return dwError; -} - - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateAddUpdateSection( DNS_UPDATE_REQUEST * pDNSRequest, - DNS_RR_RECORD * pDNSRecord ) -{ - int32 dwError = 0; - int16 wNumUpdates = 0; - - wNumUpdates = pDNSRequest->wUpdates; - dwError = DNSReallocMemory( pDNSRequest->ppUpdateRRSet, - ( void * ) &pDNSRequest->ppUpdateRRSet, - ( wNumUpdates + - 1 ) * sizeof( DNS_RR_RECORD * ) ); - BAIL_ON_ERROR( dwError ); - - *( pDNSRequest->ppUpdateRRSet + wNumUpdates ) = pDNSRecord; - - pDNSRequest->wUpdates += 1; - - error: - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateCreateUpdateRequest( DNS_UPDATE_REQUEST ** ppDNSRequest ) -{ - int32 dwError = 0; - DNS_UPDATE_REQUEST *pDNSRequest = NULL; - - dwError = - DNSAllocateMemory( sizeof( DNS_UPDATE_REQUEST ), - ( void * ) &pDNSRequest ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSGenerateIdentifier( &pDNSRequest->wIdentification ); - BAIL_ON_ERROR( dwError ); - - pDNSRequest->wParameter = 0x2800; - - *ppDNSRequest = pDNSRequest; - - return dwError; - - error: - - if ( pDNSRequest ) { - DNSUpdateFreeRequest( pDNSRequest ); - } - *ppDNSRequest = NULL; - return dwError; -} diff --git a/source3/libaddns/dnsupresp.c b/source3/libaddns/dnsupresp.c deleted file mode 100644 index 26cc9ff8e2..0000000000 --- a/source3/libaddns/dnsupresp.c +++ /dev/null @@ -1,397 +0,0 @@ -/* - 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" - -/********************************************************************* -*********************************************************************/ - -static int32 DNSUpdateAllocateResponse( DNS_UPDATE_RESPONSE ** ppDNSResponse ) -{ - int32 dwError = 0; - DNS_UPDATE_RESPONSE *pDNSResponse = NULL; - - dwError = - DNSAllocateMemory( sizeof( DNS_UPDATE_RESPONSE ), - ( void * ) &pDNSResponse ); - BAIL_ON_ERROR( dwError ); - - *ppDNSResponse = pDNSResponse; - - return dwError; - - error: - - *ppDNSResponse = NULL; - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSUpdateUnmarshallAdditionalSection( HANDLE hReceiveBuffer, - int16 wAdditionals, - DNS_RR_RECORD * - **pppDNSAdditionalsRRRecords ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSRRRecord = NULL; - DNS_RR_RECORD **ppDNSAdditionalRRRecords = NULL; - DNS_RR_HEADER RRHeader = { 0 }; - DNS_RR_HEADER *pRRHeader = &RRHeader; - uint8 *pRRData = NULL; - int32 dwRead = 0; - - dwError = DNSAllocateMemory( wAdditionals * sizeof( DNS_RR_RECORD * ), - ( void * ) &ppDNSAdditionalRRRecords ); - BAIL_ON_ERROR( dwError ); - - for ( i = 0; i < wAdditionals; i++ ) { - - memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) ); - dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUnmarshallRData( hReceiveBuffer, - pRRHeader->wRDataSize, &pRRData, - &dwRead ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_RR_RECORD ), - ( void * ) &pDNSRRRecord ); - BAIL_ON_ERROR( dwError ); - - memcpy( &pDNSRRRecord->RRHeader, pRRHeader, - sizeof( DNS_RR_HEADER ) ); - pDNSRRRecord->pRData = pRRData; - - *( ppDNSAdditionalRRRecords + i ) = pDNSRRRecord; - } - - error: - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSUpdateUnmarshallPRSection( HANDLE hReceiveBuffer, - int16 wPRs, - DNS_RR_RECORD * **pppDNSPRRRRecords ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSRRRecord = NULL; - DNS_RR_RECORD **ppDNSPRRRRecords = NULL; - DNS_RR_HEADER RRHeader = { 0 }; - DNS_RR_HEADER *pRRHeader = &RRHeader; - uint8 *pRRData = NULL; - int32 dwRead = 0; - - dwError = DNSAllocateMemory( wPRs * sizeof( DNS_RR_RECORD * ), - ( void * ) &ppDNSPRRRRecords ); - BAIL_ON_ERROR( dwError ); - - for ( i = 0; i < wPRs; i++ ) { - - memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) ); - dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUnmarshallRData( hReceiveBuffer, - pRRHeader->wRDataSize, &pRRData, - &dwRead ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_RR_RECORD ), - ( void * ) &pDNSRRRecord ); - BAIL_ON_ERROR( dwError ); - - memcpy( &pDNSRRRecord->RRHeader, pRRHeader, - sizeof( DNS_RR_HEADER ) ); - pDNSRRRecord->pRData = pRRData; - - *( ppDNSPRRRRecords + i ) = pDNSRRRecord; - } - - *pppDNSPRRRRecords = ppDNSPRRRRecords; - - return dwError; - - error: - - - return dwError; -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSUpdateUnmarshallUpdateSection( HANDLE hReceiveBuffer, - int16 wUpdates, - DNS_RR_RECORD * **pppDNSUpdateRRRecords ) -{ - int32 dwError = 0; - int32 i = 0; - DNS_RR_RECORD *pDNSRRRecord = NULL; - DNS_RR_RECORD **ppDNSUpdateRRRecords = NULL; - DNS_RR_HEADER RRHeader = { 0 }; - DNS_RR_HEADER *pRRHeader = &RRHeader; - uint8 *pRRData = NULL; - int32 dwRead = 0; - - dwError = DNSAllocateMemory( wUpdates * sizeof( DNS_RR_RECORD * ), - ( void * ) &ppDNSUpdateRRRecords ); - BAIL_ON_ERROR( dwError ); - - for ( i = 0; i < wUpdates; i++ ) { - - memset( pRRHeader, 0, sizeof( DNS_RR_HEADER ) ); - dwError = DNSUnmarshallRRHeader( hReceiveBuffer, pRRHeader ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUnmarshallRData( hReceiveBuffer, - pRRHeader->wRDataSize, &pRRData, - &dwRead ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSAllocateMemory( sizeof( DNS_RR_RECORD ), - ( void * ) &pDNSRRRecord ); - BAIL_ON_ERROR( dwError ); - - memcpy( &pDNSRRRecord->RRHeader, pRRHeader, - sizeof( DNS_RR_HEADER ) ); - pDNSRRRecord->pRData = pRRData; - - *( ppDNSUpdateRRRecords + i ) = pDNSRRRecord; - } - - *pppDNSUpdateRRRecords = ppDNSUpdateRRRecords; - - return dwError; - - error: - - return dwError; - -} - -/********************************************************************* -*********************************************************************/ - -static int32 DNSUpdateUnmarshallZoneSection( HANDLE hReceiveBuffer, - int16 wZones, - DNS_ZONE_RECORD * **pppDNSZoneRecords ) -{ - int32 dwError = 0; - int32 i = 0; - int32 dwRead = 0; - DNS_ZONE_RECORD *pDNSZoneRecord = NULL; - DNS_ZONE_RECORD **ppDNSZoneRecords = NULL; - int16 wnZoneClass = 0; - int16 wnZoneType = 0; - - - dwError = DNSAllocateMemory( wZones * sizeof( DNS_ZONE_RECORD * ), - ( void * ) &ppDNSZoneRecords ); - BAIL_ON_ERROR( dwError ); - - for ( i = 0; i < wZones; i++ ) { - - dwError = - DNSAllocateMemory( sizeof( DNS_ZONE_RECORD ), - ( void * ) &pDNSZoneRecord ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUnmarshallDomainName( hReceiveBuffer, - &pDNSZoneRecord-> - pDomainName ); - BAIL_ON_ERROR( dwError ); - - dwError = - DNSUnmarshallBuffer( hReceiveBuffer, - ( uint8 * ) & wnZoneType, - ( int32 ) sizeof( int16 ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - pDNSZoneRecord->wZoneType = ntohs( wnZoneType ); - - dwError = - DNSUnmarshallBuffer( hReceiveBuffer, - ( uint8 * ) & wnZoneClass, - ( int32 ) sizeof( int16 ), - &dwRead ); - BAIL_ON_ERROR( dwError ); - pDNSZoneRecord->wZoneClass = ntohs( wnZoneClass ); - - *( ppDNSZoneRecords + i ) = pDNSZoneRecord; - } - - *pppDNSZoneRecords = ppDNSZoneRecords; - return dwError; - - error: - - return dwError; -} - - -/********************************************************************* -*********************************************************************/ - -int32 DNSUpdateReceiveUpdateResponse( HANDLE hDNSHandle, - DNS_UPDATE_RESPONSE ** ppDNSResponse ) -{ - DNS_UPDATE_RESPONSE *pDNSResponse = NULL; - int32 dwError = 0; - int16 wnIdentification, wIdentification = 0; - int16 wnParameter, wParameter = 0; - int16 wnZones, wZones = 0; - int16 wnPRs, wPRs = 0; - int16 wnAdditionals, wAdditionals = 0; - int16 wnUpdates, wUpdates = 0; - int32 dwRead = 0; - DNS_RR_RECORD **ppDNSPRRecords = NULL; - DNS_RR_RECORD **ppDNSAdditionalRecords = NULL; - DNS_RR_RECORD **ppDNSUpdateRecords = NULL; - DNS_ZONE_RECORD **ppDNSZoneRecords = NULL; - HANDLE hRecvBuffer = ( HANDLE ) NULL; - - dwError = DNSCreateReceiveBuffer( &hRecvBuffer ); - BAIL_ON_ERROR( dwError ); - - dwError = DNSReceiveBufferContext( hDNSHandle, hRecvBuffer, &dwRead ); - BAIL_ON_ERROR( dwError ); - -#if 0 - dwError = DNSDumpRecvBufferContext( hRecvBuffer ); - BAIL_ON_ERROR( dwError ); -#endif - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, - ( uint8 * ) & wnIdentification, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wIdentification = ntohs( wnIdentification ); - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnParameter, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wParameter = ntohs( wnParameter ); - - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnZones, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wZones = ntohs( wnZones ); - - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnPRs, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wPRs = ntohs( wnPRs ); - - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnUpdates, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wUpdates = ntohs( wnUpdates ); - - dwError = - DNSUnmarshallBuffer( hRecvBuffer, ( uint8 * ) & wnAdditionals, - sizeof( int16 ), &dwRead ); - BAIL_ON_ERROR( dwError ); - wAdditionals = ntohs( wnAdditionals ); - - - if ( wZones ) { - dwError = - DNSUpdateUnmarshallZoneSection( hRecvBuffer, wZones, - &ppDNSZoneRecords ); - BAIL_ON_ERROR( dwError ); - } - - if ( wPRs ) { - dwError = - DNSUpdateUnmarshallPRSection( hRecvBuffer, wPRs, - &ppDNSPRRecords ); - BAIL_ON_ERROR( dwError ); - } - - if ( wUpdates ) { - dwError = - DNSUpdateUnmarshallUpdateSection( hRecvBuffer, - wUpdates, - &ppDNSUpdateRecords ); - BAIL_ON_ERROR( dwError ); - } - - if ( wAdditionals ) { - dwError = - DNSUpdateUnmarshallAdditionalSection( hRecvBuffer, - wAdditionals, - &ppDNSAdditionalRecords ); - BAIL_ON_ERROR( dwError ); - } - - dwError = DNSUpdateAllocateResponse( &pDNSResponse ); - BAIL_ON_ERROR( dwError ); - - pDNSResponse->wIdentification = wIdentification; - pDNSResponse->wParameter = wParameter; - pDNSResponse->wZones = wZones; - pDNSResponse->wPRs = wPRs; - pDNSResponse->wUpdates = wUpdates; - pDNSResponse->wAdditionals = wAdditionals; - - pDNSResponse->ppZoneRRSet = ppDNSZoneRecords; - pDNSResponse->ppPRRRSet = ppDNSPRRecords; - pDNSResponse->ppUpdateRRSet = ppDNSUpdateRecords; - pDNSResponse->ppAdditionalRRSet = ppDNSAdditionalRecords; - - *ppDNSResponse = pDNSResponse; - - - error: - - return dwError; -} - 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 <ctype.h> -#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; -} - - - diff --git a/source3/utils/net_ads.c b/source3/utils/net_ads.c index 0f189f9c6f..76b6b043ba 100644 --- a/source3/utils/net_ads.c +++ b/source3/utils/net_ads.c @@ -1220,79 +1220,79 @@ static BOOL net_derive_salting_principal( TALLOC_CTX *ctx, ADS_STRUCT *ads ) *******************************************************************/ #if defined(WITH_DNS_UPDATES) -static BOOL net_update_dns( TALLOC_CTX *ctx, ADS_STRUCT *ads ) +#include "dns.h" +DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName, + const char *pszDomainName, + const char *pszHostName, + const struct in_addr *iplist, int num_addrs ); + + +static NTSTATUS net_update_dns_internal(TALLOC_CTX *ctx, ADS_STRUCT *ads, + const char *machine_name, + const struct in_addr *addrs, + int num_addrs) { - int num_addrs; - struct in_addr *iplist = NULL; struct dns_rr_ns *nameservers = NULL; int ns_count = 0; - int ret = 0; - NTSTATUS dns_status; - fstring machine_name; + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + DNS_ERROR dns_err; fstring dns_server; const char *dnsdomain; - ADS_STRUCT *ads_s = NULL; - name_to_fqdn( machine_name, global_myname() ); - strlower_m( machine_name ); if ( (dnsdomain = strchr_m( machine_name, '.')) == NULL ) { - d_printf("No DNS domain configured for %s. Unable to perform DNS Update.\n", - machine_name); + d_printf("No DNS domain configured for %s. " + "Unable to perform DNS Update.\n", machine_name); + status = NT_STATUS_INVALID_PARAMETER; goto done; } dnsdomain++; - dns_status = ads_dns_lookup_ns( ctx, dnsdomain, &nameservers, &ns_count ); - if ( !NT_STATUS_IS_OK(dns_status) || (ns_count == 0)) { - DEBUG(3,("net_ads_join: Failed to find name server for the %s realm\n", - ads->config.realm)); - goto done; - } - - /* Get our ip address (not the 127.0.0.x address but a real ip address) */ - - num_addrs = get_my_ip_address( &iplist ); - if ( num_addrs <= 0 ) { - DEBUG(4,("net_ads_join: Failed to find my non-loopback IP addresses!\n")); - ret = -1; + status = ads_dns_lookup_ns( ctx, dnsdomain, &nameservers, &ns_count ); + if ( !NT_STATUS_IS_OK(status) || (ns_count == 0)) { + DEBUG(3,("net_ads_join: Failed to find name server for the %s " + "realm\n", ads->config.realm)); goto done; } - /* Drop the user creds */ + /* Now perform the dns update - we'll try non-secure and if we fail, + we'll follow it up with a secure update */ - ads_kdestroy( NULL ); + fstrcpy( dns_server, nameservers[0].hostname ); - ads_s = ads_init( ads->server.realm, ads->server.workgroup, ads->server.ldap_server ); - if ( !ads_s ) { - DEBUG(1,("net_ads_join: ads_init() failed!\n")); - ret = -1; - goto done; + dns_err = DoDNSUpdate(ads, dns_server, dnsdomain, machine_name, addrs, num_addrs); + if (!ERR_DNS_IS_OK(dns_err)) { + status = NT_STATUS_UNSUCCESSFUL; } - /* kinit with the machine password */ +done: + return status; + } - asprintf( &ads_s->auth.user_name, "%s$", global_myname() ); - ads_s->auth.password = secrets_fetch_machine_password( lp_workgroup(), NULL, NULL ); - ads_s->auth.realm = SMB_STRDUP( lp_realm() ); - ads_kinit_password( ads_s ); +static NTSTATUS net_update_dns(TALLOC_CTX *mem_ctx, ADS_STRUCT *ads) +{ + int num_addrs; + struct in_addr *iplist = NULL; + fstring machine_name; + NTSTATUS status; - /* Now perform the dns update - we'll try non-secure and if we fail, we'll - follow it up with a secure update */ + name_to_fqdn( machine_name, global_myname() ); + strlower_m( machine_name ); - fstrcpy( dns_server, nameservers[0].hostname ); + /* Get our ip address (not the 127.0.0.x address but a real ip + * address) */ - ret = DoDNSUpdate(dns_server, dnsdomain, machine_name, iplist, num_addrs ); - if ( ret ) { - DEBUG(1, ("Error creating dns update!\n")); + num_addrs = get_my_ip_address( &iplist ); + if ( num_addrs <= 0 ) { + DEBUG(4,("net_ads_join: Failed to find my non-loopback IP " + "addresses!\n")); + return NT_STATUS_INVALID_PARAMETER; } -done: + status = net_update_dns_internal(mem_ctx, ads, machine_name, + iplist, num_addrs); SAFE_FREE( iplist ); - if ( ads_s ) - ads_destroy( &ads_s ); - - return (ret == 0); + return status; } #endif @@ -1506,8 +1506,22 @@ int net_ads_join(int argc, const char **argv) #if defined(WITH_DNS_UPDATES) /* We enter this block with user creds */ + ads_kdestroy( NULL ); + ads_destroy(&ads); + ads = NULL; + + if ( (ads = ads_init( lp_realm(), NULL, NULL )) != NULL ) { + /* kinit with the machine password */ + + use_in_memory_ccache(); + asprintf( &ads->auth.user_name, "%s$", global_myname() ); + ads->auth.password = secrets_fetch_machine_password( + lp_workgroup(), NULL, NULL ); + ads->auth.realm = SMB_STRDUP( lp_realm() ); + ads_kinit_password( ads ); + } - if ( !net_update_dns( ctx, ads ) ) { + if ( !ads || !NT_STATUS_IS_OK(net_update_dns( ctx, ads )) ) { d_fprintf( stderr, "DNS update failed!\n" ); } @@ -1554,42 +1568,72 @@ static int net_ads_dns_usage(int argc, const char **argv) /******************************************************************* ********************************************************************/ -static int net_ads_dns(int argc, const char **argv) +static int net_ads_dns_register(int argc, const char **argv) { #if defined(WITH_DNS_UPDATES) ADS_STRUCT *ads; ADS_STATUS status; TALLOC_CTX *ctx; - BOOL register_dns = False; - int i; + fstring name; + int num_addrs; + struct in_addr *iplist = NULL; - status = ads_startup(True, &ads); - if ( !ADS_ERR_OK(status) ) { - DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status))); +#ifdef DEVELOPER + talloc_enable_leak_report(); +#endif + + if (argc > 2) { + d_fprintf(stderr, "net ads dns register <name> <ip>\n"); return -1; } if (!(ctx = talloc_init("net_ads_dns"))) { - DEBUG(0, ("Could not initialise talloc context\n")); + d_fprintf(stderr, "Could not initialise talloc context\n"); return -1; } - /* process additional command line args */ + if (argc > 0) { + fstrcpy(name, argv[0]); + } else { + name_to_fqdn(name, global_myname()); + } + strlower_m(name); - for ( i=0; i<argc; i++ ) { - if ( strequal(argv[i], "register") ) { - register_dns = True; + if (argc > 1) { + if (!(iplist = SMB_MALLOC_ARRAY(struct in_addr, 1))) { + d_fprintf(stderr, "net_ads_dns_register: malloc " + "failed\n"); + return -1; } - else { - d_fprintf(stderr, "Bad option: %s\n", argv[i]); + if (inet_aton(argv[1], iplist) == 0) { + d_fprintf(stderr, "net_ads_dns_register: %s is not " + "a valid IP address\n", argv[1]); + SAFE_FREE(iplist); + return -1; + } + num_addrs = 1; + } else { + num_addrs = get_my_ip_address( &iplist ); + if ( num_addrs <= 0 ) { + d_fprintf(stderr, "net_ads_dns_regiser: Failed to " + "find my non-loopback IP addresses!\n"); return -1; } } - if ( !net_update_dns( ctx, ads ) ) { + status = ads_startup_nobind(True, &ads); + if ( !ADS_ERR_OK(status) ) { + DEBUG(1, ("error on ads_startup: %s\n", ads_errstr(status))); + TALLOC_FREE(ctx); + return -1; + } + + if ( !NT_STATUS_IS_OK(net_update_dns_internal(ctx, ads, name, + iplist, num_addrs)) ) { d_fprintf( stderr, "DNS update failed!\n" ); ads_destroy( &ads ); TALLOC_FREE( ctx ); + SAFE_FREE(iplist); return -1; } @@ -1597,6 +1641,7 @@ static int net_ads_dns(int argc, const char **argv) ads_destroy(&ads); TALLOC_FREE( ctx ); + SAFE_FREE(iplist); return 0; #else @@ -1605,6 +1650,43 @@ static int net_ads_dns(int argc, const char **argv) #endif } +#if defined(WITH_DNS_UPDATES) +DNS_ERROR do_gethostbyname(const char *server, const char *host); +#endif + +static int net_ads_dns_gethostbyname(int argc, const char **argv) +{ +#if defined(WITH_DNS_UPDATES) + DNS_ERROR err; + +#ifdef DEVELOPER + talloc_enable_leak_report(); +#endif + + if (argc != 2) { + d_fprintf(stderr, "net ads dns gethostbyname <server> " + "<name>\n"); + return -1; + } + + err = do_gethostbyname(argv[0], argv[1]); + + d_printf("do_gethostbyname returned %d\n", ERROR_DNS_V(err)); +#endif + return 0; +} + +static int net_ads_dns(int argc, const char *argv[]) +{ + struct functable func[] = { + {"REGISTER", net_ads_dns_register}, + {"GETHOSTBYNAME", net_ads_dns_gethostbyname}, + {NULL, NULL} + }; + + return net_run_function(argc, argv, func, net_ads_dns_usage); +} + /******************************************************************* ********************************************************************/ diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c index cb83b000ca..d372211a5f 100644 --- a/source3/utils/net_dns.c +++ b/source3/utils/net_dns.c @@ -30,41 +30,115 @@ /********************************************************************* *********************************************************************/ -int DoDNSUpdate( char *pszServerName, const char *pszDomainName, - char *pszHostName, struct in_addr *iplist, int num_addrs ) +DNS_ERROR DoDNSUpdate(ADS_STRUCT *ads, char *pszServerName, + const char *pszDomainName, const char *pszHostName, + const struct in_addr *iplist, int num_addrs ) { - int32 dwError = 0; - DNS_ERROR dns_status; - HANDLE hDNSServer = ( HANDLE ) NULL; - int32 dwResponseCode = 0; - DNS_UPDATE_RESPONSE *pDNSUpdateResponse = NULL; -#if 0 - DNS_UPDATE_RESPONSE *pDNSSecureUpdateResponse = NULL; -#endif + DNS_ERROR err; + struct dns_connection *conn; + TALLOC_CTX *mem_ctx; + OM_uint32 minor; + struct dns_update_request *req, *resp; if ( (num_addrs <= 0) || !iplist ) { - return -1; + return ERROR_DNS_INVALID_PARAMETER; + } + + if (!(mem_ctx = talloc_init("DoDNSUpdate"))) { + return ERROR_DNS_NO_MEMORY; } - dns_status = DNSOpen( pszServerName, DNS_TCP, &hDNSServer ); - BAIL_ON_DNS_ERROR( dns_status ); + err = dns_open( pszServerName, DNS_TCP, mem_ctx, &conn ); + if (!ERR_DNS_IS_OK(err)) { + goto error; + } + + /* + * Probe if everything's fine + */ + + err = dns_create_probe(mem_ctx, pszDomainName, pszHostName, + num_addrs, iplist, &req); + if (!ERR_DNS_IS_OK(err)) goto error; + + err = dns_update_transaction(mem_ctx, conn, req, &resp); + if (!ERR_DNS_IS_OK(err)) goto error; + + if (dns_response_code(resp->flags) == DNS_NO_ERROR) { + TALLOC_FREE(mem_ctx); + return ERROR_DNS_SUCCESS; + } + + /* + * First try without signing + */ - dwError = DNSSendUpdate( hDNSServer, pszDomainName, pszHostName, - iplist, num_addrs, &pDNSUpdateResponse ); - BAIL_ON_ERROR( dwError ); + err = dns_create_update_request(mem_ctx, pszDomainName, pszHostName, + iplist[0].s_addr, &req); + if (!ERR_DNS_IS_OK(err)) goto error; - dwError = DNSUpdateGetResponseCode( pDNSUpdateResponse, - &dwResponseCode ); - if ( dwResponseCode == DNS_REFUSED ) { - dwError = -1; + err = dns_update_transaction(mem_ctx, conn, req, &resp); + if (!ERR_DNS_IS_OK(err)) goto error; + + if (dns_response_code(resp->flags) == DNS_NO_ERROR) { + TALLOC_FREE(mem_ctx); + return ERROR_DNS_SUCCESS; + } + + /* + * Okay, we have to try with signing + */ + { + ADS_STRUCT *ads_s; + gss_ctx_id_t gss_context; + int res; + char *keyname; + + if (!(keyname = dns_generate_keyname( mem_ctx ))) { + err = ERROR_DNS_NO_MEMORY; + goto error; + } + + if (!(ads_s = ads_init(ads->server.realm, ads->server.workgroup, + ads->server.ldap_server))) { + return ERROR_DNS_NO_MEMORY; + } + + /* kinit with the machine password */ + setenv(KRB5_ENV_CCNAME, "MEMORY:net_ads", 1); + asprintf( &ads_s->auth.user_name, "%s$", global_myname() ); + ads_s->auth.password = secrets_fetch_machine_password( + lp_workgroup(), NULL, NULL ); + ads_s->auth.realm = SMB_STRDUP( lp_realm() ); + res = ads_kinit_password( ads_s ); + ads_destroy(&ads_s); + if (res) { + err = ERROR_DNS_GSS_ERROR; + goto error; + } + + err = dns_negotiate_sec_ctx( pszDomainName, pszServerName, + keyname, &gss_context ); + if (!ERR_DNS_IS_OK(err)) goto error; + + err = dns_sign_update(req, gss_context, keyname, + "gss.microsoft.com", time(NULL), 3600); + + gss_delete_sec_context(&minor, &gss_context, GSS_C_NO_BUFFER); + + if (!ERR_DNS_IS_OK(err)) goto error; + + err = dns_update_transaction(mem_ctx, conn, req, &resp); + if (!ERR_DNS_IS_OK(err)) goto error; + + err = (dns_response_code(resp->flags) == DNS_NO_ERROR) ? + ERROR_DNS_SUCCESS : ERROR_DNS_UPDATE_FAILED; } - BAIL_ON_ERROR( dwError ); -cleanup: - return dwError; error: - goto cleanup; + TALLOC_FREE(mem_ctx); + return err; } /********************************************************************* @@ -96,4 +170,23 @@ int get_my_ip_address( struct in_addr **ips ) return count; } +DNS_ERROR do_gethostbyname(const char *server, const char *host) +{ + struct dns_connection *conn; + struct dns_request *req, *resp; + DNS_ERROR err; + + err = dns_open(server, DNS_UDP, NULL, &conn); + if (!ERR_DNS_IS_OK(err)) goto error; + + err = dns_create_query(conn, host, QTYPE_A, DNS_CLASS_IN, &req); + if (!ERR_DNS_IS_OK(err)) goto error; + + err = dns_transaction(conn, conn, req, &resp); + + error: + TALLOC_FREE(conn); + return err; +} + #endif /* defined(WITH_DNS_UPDATES) */ |