2006-08-24 19:43:32 +04:00
/*
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
2007-07-10 07:52:17 +04:00
License along with this library ; if not , see < http : //www.gnu.org/licenses/>.
2006-08-24 19:43:32 +04:00
*/
# include "dns.h"
2015-06-23 11:02:17 +03:00
# include "lib/util/genrand.h"
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_query ( TALLOC_CTX * mem_ctx , const char * name ,
2012-07-05 22:47:58 +04:00
uint16_t q_type , uint16_t q_class ,
2006-11-18 00:46:26 +03:00
struct dns_request * * preq )
2006-08-24 19:43:32 +04:00
{
2011-11-23 23:59:53 +04:00
struct dns_request * req = NULL ;
struct dns_question * q = NULL ;
2006-11-18 00:46:26 +03:00
DNS_ERROR err ;
2011-06-07 05:44:43 +04:00
if ( ! ( req = talloc_zero ( mem_ctx , struct dns_request ) ) | |
2011-06-07 05:30:12 +04:00
! ( req - > questions = talloc_array ( req , struct dns_question * , 1 ) ) | |
2006-11-18 00:46:26 +03:00
! ( req - > questions [ 0 ] = talloc ( req - > questions ,
struct dns_question ) ) ) {
TALLOC_FREE ( req ) ;
return ERROR_DNS_NO_MEMORY ;
}
2006-08-24 19:43:32 +04:00
2015-06-23 11:02:17 +03:00
generate_random_buffer ( ( uint8_t * ) & req - > id , sizeof ( req - > id ) ) ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
req - > num_questions = 1 ;
q = req - > questions [ 0 ] ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_domain_name_from_string ( q , name , & q - > name ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) {
TALLOC_FREE ( req ) ;
return err ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
q - > q_type = q_type ;
q - > q_class = q_class ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
* preq = req ;
return ERROR_DNS_SUCCESS ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_update ( TALLOC_CTX * mem_ctx , const char * name ,
struct dns_update_request * * preq )
2006-08-24 19:43:32 +04:00
{
2011-11-23 23:59:53 +04:00
struct dns_update_request * req = NULL ;
struct dns_zone * z = NULL ;
2006-11-18 00:46:26 +03:00
DNS_ERROR err ;
2011-06-07 05:44:43 +04:00
if ( ! ( req = talloc_zero ( mem_ctx , struct dns_update_request ) ) | |
2011-06-07 05:30:12 +04:00
! ( req - > zones = talloc_array ( req , struct dns_zone * , 1 ) ) | |
2006-11-18 00:46:26 +03:00
! ( req - > zones [ 0 ] = talloc ( req - > zones , struct dns_zone ) ) ) {
TALLOC_FREE ( req ) ;
return ERROR_DNS_NO_MEMORY ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
req - > id = random ( ) ;
req - > flags = 0x2800 ; /* Dynamic update */
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
req - > num_zones = 1 ;
z = req - > zones [ 0 ] ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_domain_name_from_string ( z , name , & z - > name ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) {
TALLOC_FREE ( req ) ;
return err ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
z - > z_type = QTYPE_SOA ;
z - > z_class = DNS_CLASS_IN ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
* preq = req ;
return ERROR_DNS_SUCCESS ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_rrec ( TALLOC_CTX * mem_ctx , const char * name ,
2012-07-05 22:47:58 +04:00
uint16_t type , uint16_t r_class , uint32_t ttl ,
uint16_t data_length , uint8_t * data ,
2006-11-18 00:46:26 +03:00
struct dns_rrec * * prec )
2006-08-24 19:43:32 +04:00
{
2011-11-23 23:59:53 +04:00
struct dns_rrec * rec = NULL ;
2006-11-18 00:46:26 +03:00
DNS_ERROR err ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
if ( ! ( rec = talloc ( mem_ctx , struct dns_rrec ) ) ) {
return ERROR_DNS_NO_MEMORY ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
err = dns_domain_name_from_string ( rec , name , & rec - > name ) ;
if ( ! ( ERR_DNS_IS_OK ( err ) ) ) {
TALLOC_FREE ( rec ) ;
return err ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
rec - > type = type ;
rec - > r_class = r_class ;
rec - > ttl = ttl ;
rec - > data_length = data_length ;
rec - > data = talloc_move ( rec , & data ) ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
* prec = rec ;
return ERROR_DNS_SUCCESS ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_a_record ( TALLOC_CTX * mem_ctx , const char * host ,
2012-07-05 22:47:58 +04:00
uint32_t ttl , const struct sockaddr_storage * pss ,
2006-11-18 00:46:26 +03:00
struct dns_rrec * * prec )
2006-08-24 19:43:32 +04:00
{
2012-07-05 22:47:58 +04:00
uint8_t * data ;
2006-11-18 00:46:26 +03:00
DNS_ERROR err ;
2008-01-09 00:11:12 +03:00
struct in_addr ip ;
2006-08-24 19:43:32 +04:00
2008-01-09 00:11:12 +03:00
if ( pss - > ss_family ! = AF_INET ) {
2011-09-25 05:17:11 +04:00
return ERROR_DNS_INVALID_PARAMETER ;
2008-01-09 00:11:12 +03:00
}
2011-05-06 03:19:49 +04:00
ip = ( ( const struct sockaddr_in * ) pss ) - > sin_addr ;
2012-07-05 22:47:58 +04:00
if ( ! ( data = ( uint8_t * ) talloc_memdup ( mem_ctx , ( const void * ) & ip . s_addr ,
2007-02-07 14:26:36 +03:00
sizeof ( ip . s_addr ) ) ) ) {
2006-11-18 00:46:26 +03:00
return ERROR_DNS_NO_MEMORY ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_create_rrec ( mem_ctx , host , QTYPE_A , DNS_CLASS_IN , ttl ,
2007-02-07 14:26:36 +03:00
sizeof ( ip . s_addr ) , data , prec ) ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
if ( ! ERR_DNS_IS_OK ( err ) ) {
TALLOC_FREE ( data ) ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
return err ;
}
2006-08-24 19:43:32 +04:00
2011-09-25 05:17:11 +04:00
DNS_ERROR dns_create_aaaa_record ( TALLOC_CTX * mem_ctx , const char * host ,
2012-07-05 22:47:58 +04:00
uint32_t ttl , const struct sockaddr_storage * pss ,
2011-09-25 05:17:11 +04:00
struct dns_rrec * * prec )
{
# ifdef HAVE_IPV6
2012-07-05 22:47:58 +04:00
uint8_t * data ;
2011-09-25 05:17:11 +04:00
DNS_ERROR err ;
struct in6_addr ip6 ;
if ( pss - > ss_family ! = AF_INET6 ) {
return ERROR_DNS_INVALID_PARAMETER ;
}
ip6 = ( ( const struct sockaddr_in6 * ) pss ) - > sin6_addr ;
2012-07-05 22:47:58 +04:00
if ( ! ( data = ( uint8_t * ) talloc_memdup ( mem_ctx , ( const void * ) & ip6 . s6_addr ,
2011-09-25 05:17:11 +04:00
sizeof ( ip6 . s6_addr ) ) ) ) {
return ERROR_DNS_NO_MEMORY ;
}
err = dns_create_rrec ( mem_ctx , host , QTYPE_AAAA , DNS_CLASS_IN , ttl ,
sizeof ( ip6 . s6_addr ) , data , prec ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) {
TALLOC_FREE ( data ) ;
}
return err ;
# else
return ERROR_DNS_INVALID_PARAMETER ;
# endif
}
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_name_in_use_record ( TALLOC_CTX * mem_ctx ,
const char * name ,
2008-01-09 00:11:12 +03:00
const struct sockaddr_storage * ss ,
2006-11-18 00:46:26 +03:00
struct dns_rrec * * prec )
{
2008-01-09 00:11:12 +03:00
if ( ss ! = NULL ) {
2011-09-25 05:17:11 +04:00
switch ( ss - > ss_family ) {
case AF_INET :
return dns_create_a_record ( mem_ctx , name , 0 , ss , prec ) ;
# ifdef HAVE_IPV6
case AF_INET6 :
return dns_create_aaaa_record ( mem_ctx , name , 0 , ss , prec ) ;
# endif
default :
return ERROR_DNS_INVALID_PARAMETER ;
}
2006-11-18 00:46:26 +03:00
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
return dns_create_rrec ( mem_ctx , name , QTYPE_ANY , DNS_CLASS_IN , 0 , 0 ,
NULL , prec ) ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_name_not_in_use_record ( TALLOC_CTX * mem_ctx ,
2012-07-05 22:47:58 +04:00
const char * name , uint32_t type ,
2006-11-18 00:46:26 +03:00
struct dns_rrec * * prec )
{
return dns_create_rrec ( mem_ctx , name , type , DNS_CLASS_NONE , 0 ,
0 , NULL , prec ) ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_delete_record ( TALLOC_CTX * mem_ctx , const char * name ,
2012-07-05 22:47:58 +04:00
uint16_t type , uint16_t r_class ,
2006-11-18 00:46:26 +03:00
struct dns_rrec * * prec )
{
return dns_create_rrec ( mem_ctx , name , type , r_class , 0 , 0 , NULL , prec ) ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_tkey_record ( TALLOC_CTX * mem_ctx , const char * keyname ,
const char * algorithm_name , time_t inception ,
2012-07-05 22:47:58 +04:00
time_t expiration , uint16_t mode , uint16_t error ,
uint16_t key_length , const uint8_t * key ,
2006-11-18 00:46:26 +03:00
struct dns_rrec * * prec )
{
2011-11-23 23:59:53 +04:00
struct dns_buffer * buf = NULL ;
struct dns_domain_name * algorithm = NULL ;
2006-11-18 00:46:26 +03:00
DNS_ERROR err ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
if ( ! ( buf = dns_create_buffer ( mem_ctx ) ) ) {
return ERROR_DNS_NO_MEMORY ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
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 ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_create_rrec ( mem_ctx , keyname , QTYPE_TKEY , DNS_CLASS_ANY , 0 ,
buf - > offset , buf - > data , prec ) ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
error :
TALLOC_FREE ( buf ) ;
return err ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
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 ;
2012-07-05 22:47:58 +04:00
uint32_t tmp_inception , tmp_expiration ;
2006-11-18 00:46:26 +03:00
if ( ! ( tkey = talloc ( mem_ctx , struct dns_tkey_record ) ) ) {
return ERROR_DNS_NO_MEMORY ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
buf . data = rec - > data ;
buf . size = rec - > data_length ;
buf . offset = 0 ;
buf . error = ERROR_DNS_SUCCESS ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
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 ) ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
if ( ! ERR_DNS_IS_OK ( buf . error ) ) goto error ;
2006-08-24 19:43:32 +04:00
2007-04-30 06:39:34 +04:00
if ( tkey - > key_length ) {
2012-07-05 22:47:58 +04:00
if ( ! ( tkey - > key = talloc_array ( tkey , uint8_t , tkey - > key_length ) ) ) {
2007-04-30 06:39:34 +04:00
buf . error = ERROR_DNS_NO_MEMORY ;
goto error ;
}
} else {
tkey - > key = NULL ;
2006-11-18 00:46:26 +03:00
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
dns_unmarshall_buffer ( & buf , tkey - > key , tkey - > key_length ) ;
if ( ! ERR_DNS_IS_OK ( buf . error ) ) goto error ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
tkey - > inception = ( time_t ) tmp_inception ;
tkey - > expiration = ( time_t ) tmp_expiration ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
* ptkey = tkey ;
return ERROR_DNS_SUCCESS ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
error :
TALLOC_FREE ( tkey ) ;
return buf . error ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_tsig_record ( TALLOC_CTX * mem_ctx , const char * keyname ,
const char * algorithm_name ,
2012-07-05 22:47:58 +04:00
time_t time_signed , uint16_t fudge ,
uint16_t mac_length , const uint8_t * mac ,
uint16_t original_id , uint16_t error ,
2006-11-18 00:46:26 +03:00
struct dns_rrec * * prec )
{
2011-11-23 03:53:26 +04:00
struct dns_buffer * buf = NULL ;
struct dns_domain_name * algorithm = NULL ;
2006-11-18 00:46:26 +03:00
DNS_ERROR err ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
if ( ! ( buf = dns_create_buffer ( mem_ctx ) ) ) {
return ERROR_DNS_NO_MEMORY ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
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 ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
err = dns_create_rrec ( mem_ctx , keyname , QTYPE_TSIG , DNS_CLASS_ANY , 0 ,
buf - > offset , buf - > data , prec ) ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
error :
TALLOC_FREE ( buf ) ;
return err ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_add_rrec ( TALLOC_CTX * mem_ctx , struct dns_rrec * rec ,
2012-07-05 22:47:58 +04:00
uint16_t * num_records , struct dns_rrec * * * records )
2006-08-24 19:43:32 +04:00
{
2006-11-18 00:46:26 +03:00
struct dns_rrec * * new_records ;
2006-08-24 19:43:32 +04:00
2011-06-07 05:10:15 +04:00
if ( ! ( new_records = talloc_realloc ( mem_ctx , * records ,
2006-11-18 00:46:26 +03:00
struct dns_rrec * ,
( * num_records ) + 1 ) ) ) {
return ERROR_DNS_NO_MEMORY ;
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
new_records [ * num_records ] = talloc_move ( new_records , & rec ) ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
* num_records + = 1 ;
* records = new_records ;
return ERROR_DNS_SUCCESS ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
/*
* 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 ,
2008-01-09 00:11:12 +03:00
const struct sockaddr_storage * sslist ,
2006-11-18 00:46:26 +03:00
struct dns_update_request * * preq )
2006-08-24 19:43:32 +04:00
{
2011-11-23 23:59:53 +04:00
struct dns_update_request * req = NULL ;
struct dns_rrec * rec = NULL ;
2006-11-18 00:46:26 +03:00
DNS_ERROR err ;
2012-07-05 22:47:58 +04:00
uint16_t i ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_create_update ( mem_ctx , zone , & req ) ;
2011-11-22 14:26:04 +04:00
if ( ! ERR_DNS_IS_OK ( err ) ) return err ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_create_name_not_in_use_record ( req , host , QTYPE_CNAME , & rec ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) goto error ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_add_rrec ( req , rec , & req - > num_preqs , & req - > preqs ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) goto error ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
for ( i = 0 ; i < num_ips ; i + + ) {
err = dns_create_name_in_use_record ( req , host ,
2008-01-09 00:11:12 +03:00
& sslist [ i ] , & rec ) ;
2006-11-18 00:46:26 +03:00
if ( ! ERR_DNS_IS_OK ( err ) ) goto error ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_add_rrec ( req , rec , & req - > num_preqs , & req - > preqs ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) goto error ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
* preq = req ;
return ERROR_DNS_SUCCESS ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
error :
TALLOC_FREE ( req ) ;
return err ;
2006-08-24 19:43:32 +04:00
}
2006-11-18 00:46:26 +03:00
DNS_ERROR dns_create_update_request ( TALLOC_CTX * mem_ctx ,
const char * domainname ,
const char * hostname ,
2008-01-09 00:11:12 +03:00
const struct sockaddr_storage * ss_addrs ,
2006-12-14 19:27:45 +03:00
size_t num_addrs ,
2023-02-16 20:36:37 +03:00
uint32_t ttl ,
2006-11-18 00:46:26 +03:00
struct dns_update_request * * preq )
2006-08-24 19:43:32 +04:00
{
2011-11-23 23:59:53 +04:00
struct dns_update_request * req = NULL ;
struct dns_rrec * rec = NULL ;
2006-11-18 00:46:26 +03:00
DNS_ERROR err ;
2008-01-09 00:11:12 +03:00
size_t i ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_create_update ( mem_ctx , domainname , & req ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) return err ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
/*
2008-10-03 19:51:21 +04:00
* Use the same prereq as WinXP - - No CNAME records for this host .
2006-11-18 00:46:26 +03:00
*/
2006-08-24 19:43:32 +04:00
2008-10-03 19:51:21 +04:00
err = dns_create_rrec ( req , hostname , QTYPE_CNAME , DNS_CLASS_NONE ,
2006-11-18 00:46:26 +03:00
0 , 0 , NULL , & rec ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) goto error ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_add_rrec ( req , rec , & req - > num_preqs , & req - > preqs ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) goto error ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
/*
2020-12-22 19:23:16 +03:00
* Delete all existing RRsets from our name
2006-11-18 00:46:26 +03:00
*/
2006-08-24 19:43:32 +04:00
2020-12-22 19:23:16 +03:00
err = dns_create_delete_record ( req , hostname , QTYPE_ANY , DNS_CLASS_ANY ,
2006-11-18 00:46:26 +03:00
& rec ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) goto error ;
2008-01-09 00:11:12 +03:00
2006-11-18 00:46:26 +03:00
err = dns_add_rrec ( req , rec , & req - > num_updates , & req - > updates ) ;
if ( ! ERR_DNS_IS_OK ( err ) ) goto error ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
/*
2006-12-14 19:27:45 +03:00
* . . and add our IPs
2006-11-18 00:46:26 +03:00
*/
2006-08-24 19:43:32 +04:00
2008-01-09 00:11:12 +03:00
for ( i = 0 ; i < num_addrs ; i + + ) {
2011-09-25 05:17:11 +04:00
switch ( ss_addrs [ i ] . ss_family ) {
case AF_INET :
2023-02-16 20:36:37 +03:00
err = dns_create_a_record ( req ,
hostname ,
ttl ,
& ss_addrs [ i ] ,
& rec ) ;
2011-09-25 05:17:11 +04:00
break ;
# ifdef HAVE_IPV6
case AF_INET6 :
2023-02-16 20:36:37 +03:00
err = dns_create_aaaa_record ( req ,
hostname ,
ttl ,
& ss_addrs [ i ] ,
& rec ) ;
2011-09-25 05:17:11 +04:00
break ;
# endif
default :
continue ;
}
2008-01-09 00:11:12 +03:00
if ( ! ERR_DNS_IS_OK ( err ) )
2006-12-14 19:27:45 +03:00
goto error ;
2006-08-24 19:43:32 +04:00
2006-12-14 19:27:45 +03:00
err = dns_add_rrec ( req , rec , & req - > num_updates , & req - > updates ) ;
2008-01-09 00:11:12 +03:00
if ( ! ERR_DNS_IS_OK ( err ) )
2006-12-14 19:27:45 +03:00
goto error ;
2008-01-09 00:11:12 +03:00
}
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
* preq = req ;
return ERROR_DNS_SUCCESS ;
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
error :
TALLOC_FREE ( req ) ;
return err ;
2006-08-24 19:43:32 +04:00
}