2006-08-24 19:43:32 +04:00
/*
Samba Unix / Linux Dynamic DNS Update
net ads commands
Copyright ( C ) Krishna Ganugapati ( krishnag @ centeris . com ) 2006
Copyright ( C ) Gerald Carter 2006
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2006-08-24 19:43:32 +04:00
( at your option ) any later version .
2010-07-18 15:39:51 +04:00
2006-08-24 19:43:32 +04:00
This program 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 General Public License for more details .
2010-07-18 15:39:51 +04:00
2006-08-24 19:43:32 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2006-08-24 19:43:32 +04:00
*/
# include "includes.h"
# include "utils/net.h"
2011-03-04 15:16:40 +03:00
# include "../lib/addns/dns.h"
2006-08-24 19:43:32 +04:00
# if defined(WITH_DNS_UPDATES)
2007-07-25 22:45:57 +04:00
/*
* Silly prototype to get rid of a warning
*/
DNS_ERROR DoDNSUpdate ( char * pszServerName ,
const char * pszDomainName , const char * pszHostName ,
2008-01-15 00:38:16 +03:00
const struct sockaddr_storage * sslist ,
size_t num_addrs ) ;
2007-07-25 22:45:57 +04:00
2006-08-24 19:43:32 +04:00
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2006-12-14 20:00:10 +03:00
DNS_ERROR DoDNSUpdate ( char * pszServerName ,
2006-11-18 00:46:26 +03:00
const char * pszDomainName , const char * pszHostName ,
2008-01-09 00:11:12 +03:00
const struct sockaddr_storage * sslist , size_t num_addrs )
2006-08-24 19:43:32 +04:00
{
2006-11-18 00:46:26 +03:00
DNS_ERROR err ;
struct dns_connection * conn ;
TALLOC_CTX * mem_ctx ;
OM_uint32 minor ;
struct dns_update_request * req , * resp ;
2006-08-24 19:43:32 +04:00
2008-01-09 13:44:40 +03:00
if ( ( num_addrs < = 0 ) | | ! sslist ) {
2006-11-18 00:46:26 +03:00
return ERROR_DNS_INVALID_PARAMETER ;
}
if ( ! ( mem_ctx = talloc_init ( " DoDNSUpdate " ) ) ) {
return ERROR_DNS_NO_MEMORY ;
2006-08-24 19:43:32 +04:00
}
2010-07-18 15:39:51 +04:00
2006-12-31 09:50:44 +03:00
err = dns_open_connection ( pszServerName , DNS_TCP , mem_ctx , & conn ) ;
2006-11-18 00:46:26 +03:00
if ( ! ERR_DNS_IS_OK ( err ) ) {
goto error ;
}
/*
* Probe if everything ' s fine
*/
err = dns_create_probe ( mem_ctx , pszDomainName , pszHostName ,
2008-01-09 00:11:12 +03:00
num_addrs , sslist , & req ) ;
2006-11-18 00:46:26 +03:00
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
*/
2006-08-24 19:43:32 +04:00
2006-11-18 00:46:26 +03:00
err = dns_create_update_request ( mem_ctx , pszDomainName , pszHostName ,
2008-01-09 00:11:12 +03:00
sslist , num_addrs , & req ) ;
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_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
*/
{
gss_ctx_id_t gss_context ;
char * keyname ;
if ( ! ( keyname = dns_generate_keyname ( mem_ctx ) ) ) {
err = ERROR_DNS_NO_MEMORY ;
goto error ;
}
err = dns_negotiate_sec_ctx ( pszDomainName , pszServerName ,
2006-12-14 19:27:45 +03:00
keyname , & gss_context , DNS_SRV_ANY ) ;
/* retry using the Windows 2000 DNS hack */
if ( ! ERR_DNS_IS_OK ( err ) ) {
err = dns_negotiate_sec_ctx ( pszDomainName , pszServerName ,
keyname , & gss_context ,
DNS_SRV_WIN2000 ) ;
}
2010-07-18 15:39:51 +04:00
2006-12-14 19:27:45 +03:00
if ( ! ERR_DNS_IS_OK ( err ) )
goto error ;
2006-11-18 00:46:26 +03:00
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 ;
2006-08-24 19:43:32 +04:00
}
error :
2006-11-18 00:46:26 +03:00
TALLOC_FREE ( mem_ctx ) ;
return err ;
2006-08-24 19:43:32 +04:00
}
/*********************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-01-09 00:11:12 +03:00
int get_my_ip_address ( struct sockaddr_storage * * pp_ss )
2006-08-24 19:43:32 +04:00
{
int i , n ;
2008-01-09 00:11:12 +03:00
struct sockaddr_storage * list = NULL ;
2006-08-24 19:43:32 +04:00
int count = 0 ;
2008-10-03 19:51:54 +04:00
/* Honor the configured list of interfaces to register */
2006-08-24 19:43:32 +04:00
2008-10-03 19:51:54 +04:00
load_interfaces ( ) ;
n = iface_count ( ) ;
2008-01-09 00:11:12 +03:00
if ( n < = 0 ) {
return - 1 ;
}
if ( ( list = SMB_MALLOC_ARRAY ( struct sockaddr_storage , n ) ) = = NULL ) {
2006-08-24 19:43:32 +04:00
return - 1 ;
}
for ( i = 0 ; i < n ; i + + ) {
2008-10-03 19:51:54 +04:00
const struct sockaddr_storage * nic_sa_storage = NULL ;
if ( ( nic_sa_storage = iface_n_sockaddr_storage ( i ) ) = = NULL )
continue ;
/* Don't register loopback addresses */
2011-09-26 00:24:50 +04:00
if ( is_loopback_addr ( ( const struct sockaddr * ) nic_sa_storage ) ) {
2008-01-09 00:11:12 +03:00
continue ;
}
2008-10-03 19:51:54 +04:00
2011-09-25 05:18:14 +04:00
/* Don't register link-local addresses */
if ( is_linklocal_addr ( nic_sa_storage ) ) {
continue ;
}
2008-10-03 19:51:54 +04:00
memcpy ( & list [ count + + ] , nic_sa_storage , sizeof ( struct sockaddr_storage ) ) ;
2006-08-24 19:43:32 +04:00
}
2008-01-09 13:44:40 +03:00
* pp_ss = list ;
2006-08-24 19:43:32 +04:00
return count ;
}
2007-07-25 22:45:57 +04:00
/*
* Silly prototype to get rid of a warning
*/
DNS_ERROR do_gethostbyname ( const char * server , const char * host ) ;
2006-11-18 00:46:26 +03:00
DNS_ERROR do_gethostbyname ( const char * server , const char * host )
{
struct dns_connection * conn ;
struct dns_request * req , * resp ;
DNS_ERROR err ;
2006-12-31 09:50:44 +03:00
err = dns_open_connection ( server , DNS_UDP , NULL , & conn ) ;
2006-11-18 00:46:26 +03:00
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 ;
}
2006-08-24 19:43:32 +04:00
# endif /* defined(WITH_DNS_UPDATES) */