From 5693e6c599a586b1bb19eea375c6b1e22526031c Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Aug 2006 15:43:32 +0000 Subject: r17798: Beginnings of a standalone libaddns library released under the LGPL. Original code by Krishna Ganugapati . Additional work by me. It's still got some warts, but non-secure updates do currently work. There are at least four things left to really clean up. 1. Change the memory management to use talloc() rather than malloc() and cleanup the leaks. 2. Fix the error code reporting (see initial changes to dnserr.h) 3. Fix the secure updates 4. Define a public interface in addns.h 5. Move the code in libads/dns.c into the libaddns/ directory (and under the LGPL). A few notes: * Enable the new code by compiling with --with-dnsupdate * Also adds the command 'net ads dns register' * Requires -luuid (included in the e2fsprogs-devel package). * Has only been tested on Linux platforms so there may be portability issues. (This used to be commit 36f04674aeefd93c5a0408b8967dcd48b86fdbc1) --- source3/libaddns/dnsgss.c | 550 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 550 insertions(+) create mode 100644 source3/libaddns/dnsgss.c (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c new file mode 100644 index 0000000000..d710604b01 --- /dev/null +++ b/source3/libaddns/dnsgss.c @@ -0,0 +1,550 @@ +/* + Public Interface file for Linux DNS client library implementation + + Copyright (C) 2006 Krishna Ganugapati + Copyright (C) 2006 Gerald Carter + + ** 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 + + +/********************************************************************* +*********************************************************************/ + +static int strupr( char *szDomainName ) +{ + if ( !szDomainName ) { + return ( 0 ); + } + while ( *szDomainName != '\0' ) { + *szDomainName = toupper( *szDomainName ); + szDomainName++; + } + return ( 0 ); +} + +/********************************************************************* +*********************************************************************/ + +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( PCtxtHandle 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( PCtxtHandle pGSSContext, + DNS_RR_RECORD * pClientTKeyRecord, + DNS_RESPONSE * pDNSResponse, + uint8 ** ppServerKeyData, + int16 * pwServerKeyDataSize ) +{ + int32 dwError = 0; + DNS_RR_RECORD *pTKeyRecord = NULL; + int16 wRCode = 0; + uint8 *pServerKeyData = NULL; + int16 wServerKeyDataSize = 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 = 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 ) +{ + 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; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSResponseGetTKeyRecord( DNS_RESPONSE * pDNSResponse, + DNS_RR_RECORD ** ppTKeyRecord ) +{ + int32 dwError = 0; + int16 wAnswers = 0; + DNS_RR_RECORD *pDNSRecord = NULL; + int32 i = 0; + + + wAnswers = pDNSResponse->wAnswers; + if ( !wAnswers ) { + dwError = ERROR_INVALID_PARAMETER; + BAIL_ON_ERROR( dwError ); + } + + for ( i = 0; i < wAnswers; i++ ) { + pDNSRecord = *( pDNSResponse->ppAnswerRRSet + i ); + if ( pDNSRecord->RRHeader.wType == QTYPE_TKEY ) { + *ppTKeyRecord = pDNSRecord; + return dwError; + } + } + dwError = ERROR_RECORD_NOT_FOUND; + + error: + *ppTKeyRecord = NULL; + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSResponseGetTSIGRecord( DNS_RESPONSE * pDNSResponse, + DNS_RR_RECORD ** ppTSIGRecord ) +{ + int32 dwError = 0; + int16 wAdditionals = 0; + DNS_RR_RECORD *pDNSRecord = NULL; + + int32 i = 0; + + wAdditionals = pDNSResponse->wAdditionals; + if ( !wAdditionals ) { + dwError = ERROR_INVALID_PARAMETER; + BAIL_ON_ERROR( dwError ); + } + + 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; + + error: + *ppTSIGRecord = NULL; + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSCompareTKeyRecord( DNS_RR_RECORD * pClientTKeyRecord, + DNS_RR_RECORD * pTKeyRecord ) +{ + int32 dwError = 0; + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSNegotiateContextAndSecureUpdate( HANDLE hDNSServer, + char *szServiceName, + char *szDomainName, + char *szHost, int32 dwIPAddress ) +{ + int32 dwError = 0; + char *pszKeyName = NULL; + CtxtHandle ContextHandle = 0; + CtxtHandle *pContextHandle = &ContextHandle; + + dwError = DNSGenerateKeyName( &pszKeyName ); + BAIL_ON_ERROR( dwError ); + + dwError = + DNSNegotiateSecureContext( hDNSServer, szDomainName, szHost, + pszKeyName, pContextHandle ); + BAIL_ON_ERROR( dwError ); + + error: + + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +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; + + DNSRecordGenerateOffsets( pTKeyRecord ); + dwKeyDataSizeOffset = pTKeyRecord->Offsets.TKey.wKeySizeOffset; + dwKeyDataOffset = pTKeyRecord->Offsets.TKey.wKeyDataOffset; + memcpy( &wnKeyDataSize, pTKeyRecord->pRData + dwKeyDataSizeOffset, + sizeof( int16 ) ); + wKeyDataSize = ntohs( wnKeyDataSize ); + + dwError = DNSAllocateMemory( wKeyDataSize, ( void ** ) &pKeyData ); + BAIL_ON_ERROR( dwError ); + + memcpy( pKeyData, pTKeyRecord->pRData + dwKeyDataOffset, + wKeyDataSize ); + + *ppKeyData = pKeyData; + *pwKeyDataSize = wKeyDataSize; + + return dwError; + + + error: + + *ppKeyData = NULL; + *pwKeyDataSize = 0; + return dwError; +} + +/********************************************************************* +*********************************************************************/ + +int32 DNSNegotiateSecureContext( HANDLE hDNSServer, + char *szDomain, + char *szServerName, + char *szKeyName, PCtxtHandle pGSSContext ) +{ + 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; + + uint8 *pServerKeyData = NULL; + int16 wServerKeyDataSize = 0; + + OM_uint32 ret_flags = 0; + + int32 dwMinorStatus = 0; + gss_name_t targ_name; + gss_cred_id_t creds; + + krb5_principal host_principal; + krb5_context 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" ) }; + + input_desc.value = NULL; + input_desc.length = 0; + + dns_status = DNSOpen( szServerName, DNS_TCP, &hDNSTcpServer ); + BAIL_ON_DNS_ERROR( dns_status ); + + + memset( szUpperCaseDomain, 0, sizeof( szUpperCaseDomain ) ); + memcpy( szUpperCaseDomain, szDomain, strlen( szDomain ) ); + strupr( szUpperCaseDomain ); + + 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 ); + + sprintf( szTargetName, "dns/%s@%s", szServerName, szUpperCaseDomain ); + printf( "%s\n", szTargetName ); + + krb5_init_context( &ctx ); + krb5_parse_name( ctx, szTargetName, &host_principal ); + krb5_free_context( ctx ); + + 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 ); + + memset( pGSSContext, 0, sizeof( CtxtHandle ) ); + *pGSSContext = GSS_C_NO_CONTEXT; + + 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, + 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, + 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 ); + } + + } while ( dwMajorStatus == GSS_S_CONTINUE_NEEDED ); + + /* If we arrive here, we have a valid security context */ + + sec_error: + error: + + return dwError; + +} + +/********************************************************************* +*********************************************************************/ + +static void display_status_1( const char *m, OM_uint32 code, int type ) +{ + 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 ); + + if ( !msg_ctx ) + break; + } +} + +/********************************************************************* +*********************************************************************/ + +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 ); +} -- cgit From bfbe5a50c66bdd77d5805644145f0c1e53684a5d Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 24 Aug 2006 18:09:05 +0000 Subject: r17802: trying to fix more build farm hosts (This used to be commit d16fea385aba11b6dad141298694320c803bf3eb) --- source3/libaddns/dnsgss.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index d710604b01..b4c1500661 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -28,6 +28,8 @@ #include +#ifdef HAVE_GSSAPI_SUPPORT + /********************************************************************* *********************************************************************/ @@ -89,7 +91,7 @@ int32 DNSBuildTKeyQueryRequest( char *szKeyName, /********************************************************************* *********************************************************************/ -int32 DNSVerifyResponseMessage_GSSSuccess( PCtxtHandle pGSSContext, +int32 DNSVerifyResponseMessage_GSSSuccess( gss_ctx_id_t * pGSSContext, DNS_RR_RECORD * pClientTKeyRecord, DNS_RESPONSE * pDNSResponse ) { @@ -133,7 +135,7 @@ int32 DNSVerifyResponseMessage_GSSSuccess( PCtxtHandle pGSSContext, /********************************************************************* *********************************************************************/ -int32 DNSVerifyResponseMessage_GSSContinue( PCtxtHandle pGSSContext, +int32 DNSVerifyResponseMessage_GSSContinue( gss_ctx_id_t * pGSSContext, DNS_RR_RECORD * pClientTKeyRecord, DNS_RESPONSE * pDNSResponse, uint8 ** ppServerKeyData, @@ -283,8 +285,8 @@ int32 DNSNegotiateContextAndSecureUpdate( HANDLE hDNSServer, { int32 dwError = 0; char *pszKeyName = NULL; - CtxtHandle ContextHandle = 0; - CtxtHandle *pContextHandle = &ContextHandle; + gss_ctx_id_t ContextHandle = 0; + gss_ctx_id_t *pContextHandle = &ContextHandle; dwError = DNSGenerateKeyName( &pszKeyName ); BAIL_ON_ERROR( dwError ); @@ -344,7 +346,7 @@ int32 DNSGetTKeyData( DNS_RR_RECORD * pTKeyRecord, int32 DNSNegotiateSecureContext( HANDLE hDNSServer, char *szDomain, char *szServerName, - char *szKeyName, PCtxtHandle pGSSContext ) + char *szKeyName, gss_ctx_id_t * pGSSContext ) { int32 dwError = 0; int32 dwMajorStatus = 0; @@ -413,7 +415,7 @@ int32 DNSNegotiateSecureContext( HANDLE hDNSServer, BAIL_ON_SEC_ERROR( dwMajorStatus ); printf( "After gss_import_name %d\n", dwMajorStatus ); - memset( pGSSContext, 0, sizeof( CtxtHandle ) ); + memset( pGSSContext, 0, sizeof( gss_ctx_id_t ) ); *pGSSContext = GSS_C_NO_CONTEXT; do { @@ -548,3 +550,5 @@ 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 ); } + +#endif /* HAVE_GSSAPI_SUPPORT */ -- cgit From 49a3f72ebbf2ace388d0b6a488a9ae0b2c5675ac Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 24 Aug 2006 20:17:59 +0000 Subject: r17805: Sorry Jerry, I could not stand the warnings... :-) (This used to be commit f5fcafd77e8a749659ef90296402c5130f45419b) --- source3/libaddns/dnsgss.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index b4c1500661..862f5e7b58 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -321,7 +321,7 @@ int32 DNSGetTKeyData( DNS_RR_RECORD * pTKeyRecord, sizeof( int16 ) ); wKeyDataSize = ntohs( wnKeyDataSize ); - dwError = DNSAllocateMemory( wKeyDataSize, ( void ** ) &pKeyData ); + dwError = DNSAllocateMemory( wKeyDataSize, ( void * ) &pKeyData ); BAIL_ON_ERROR( dwError ); memcpy( pKeyData, pTKeyRecord->pRData + dwKeyDataOffset, @@ -444,7 +444,7 @@ int32 DNSNegotiateSecureContext( HANDLE hDNSServer, if ( output_desc.length != 0 ) { dwError = DNSBuildTKeyQueryRequest( szKeyName, - output_desc. + (uint8 *)output_desc. value, output_desc. length, @@ -475,7 +475,7 @@ int32 DNSNegotiateSecureContext( HANDLE hDNSServer, if ( output_desc.length != 0 ) { dwError = DNSBuildTKeyQueryRequest( szKeyName, - output_desc. + (uint8 *)output_desc. value, output_desc. length, -- cgit From c2aae726ea3f697c50f8d2304e2a9e69c56ab90f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 17 Nov 2006 21:46:26 +0000 Subject: r19762: libaddns/*[ch] code fixes donated by Centeris Corporation (http://www.centeris.com/) under my copyright. * Rework error reporting to use DNS_ERROR instead of int32 * Convert memory allocation to use talloc() * Generalize the DNS request/response packet marshalling * Fix the secure update requests (This used to be commit c78798333616c3f823514df0f58da2eb3a30a988) --- source3/libaddns/dnsgss.c | 620 +++++++++++++++------------------------------- 1 file changed, 197 insertions(+), 423 deletions(-) (limited to 'source3/libaddns/dnsgss.c') 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 */ -- cgit From 0d38f8af3946ed14be95430286465436829507ba Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 1 Dec 2006 14:18:35 +0000 Subject: r19977: * Fix a crash in the secure DNS update code. Don't free the host_principal memory while it is still being referenced by the gss code. (This used to be commit 7a5a12e892171f0e1b6355f84ee920307834c81f) --- source3/libaddns/dnsgss.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index fc674a7b81..3d1a038363 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -243,10 +243,9 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, major = gss_import_name( &minor, &input_name, &nt_host_oid_desc, &targ_name ); - krb5_free_principal( krb_ctx, host_principal ); - krb5_free_context( krb_ctx ); - if (major) { + krb5_free_principal( krb_ctx, host_principal ); + krb5_free_context( krb_ctx ); err = ERROR_DNS_GSS_ERROR; goto error; } @@ -254,6 +253,8 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname, targ_name, gss_ctx); + krb5_free_principal( krb_ctx, host_principal ); + krb5_free_context( krb_ctx ); gss_release_name( &minor, &targ_name ); error: -- cgit From d879aa8f3617b256a16889d04a39a25b27f5bb39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 14 Dec 2006 16:27:45 +0000 Subject: r20170: Fix secure DNS updates to work against Wnidows 2000 DNS which expects the TKEY payload to be in the answer section and not in the additional set of records (like Windows 2003 and the RFC). (This used to be commit a3b6734fdad5fd92dbec075ebcd8d7044aac45c2) --- source3/libaddns/dnsgss.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index 3d1a038363..5be13a3b77 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -45,6 +45,7 @@ static int strupr( char *szDomainName ) return ( 0 ); } +#if 0 /********************************************************************* *********************************************************************/ @@ -76,12 +77,14 @@ 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 ); } +#endif 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 ) + gss_ctx_id_t *ctx, + enum dns_ServerType srv_type ) { struct gss_buffer_desc_struct input_desc, *input_ptr, output_desc; OM_uint32 major, minor; @@ -123,11 +126,21 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx, req, keyname, "gss.microsoft.com", t, t + 86400, DNS_TKEY_MODE_GSSAPI, 0, output_desc.length, (uint8 *)output_desc.value, - &rec); + &rec ); if (!ERR_DNS_IS_OK(err)) goto error; - err = dns_add_rrec(req, rec, &req->num_additionals, - &req->additionals); + /* Windows 2000 DNS is broken and requires the + TKEY payload in the Answer section instead + of the Additional seciton like Windows 2003 */ + + if ( srv_type == DNS_SRV_WIN2000 ) { + err = dns_add_rrec(req, rec, &req->num_answers, + &req->answers); + } else { + 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); @@ -163,6 +176,7 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx, */ if ((resp->num_additionals != 1) || + (resp->num_answers == 0) || (resp->answers[0]->type != QTYPE_TKEY)) { err = ERROR_DNS_INVALID_MESSAGE; goto error; @@ -194,7 +208,8 @@ static DNS_ERROR dns_negotiate_gss_ctx_int( TALLOC_CTX *mem_ctx, DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, const char *servername, const char *keyname, - gss_ctx_id_t *gss_ctx ) + gss_ctx_id_t *gss_ctx, + enum dns_ServerType srv_type ) { OM_uint32 major, minor; @@ -250,12 +265,12 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, goto error; } - err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname, targ_name, - gss_ctx); + err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname, + targ_name, gss_ctx, srv_type ); + gss_release_name( &minor, &targ_name ); krb5_free_principal( krb_ctx, host_principal ); krb5_free_context( krb_ctx ); - gss_release_name( &minor, &targ_name ); error: TALLOC_FREE(mem_ctx); -- cgit From 1beb6f6038560920dcb6944993bf1d28b238598a Mon Sep 17 00:00:00 2001 From: James Peach Date: Sun, 31 Dec 2006 06:45:24 +0000 Subject: r20427: Rename dnp_open. This conflicts with the dns_open symbol in libSystem on Mac OS X. (This used to be commit 585ee7f31d2fb169e9dc37fd786faa8049be5e52) --- source3/libaddns/dnsgss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index 5be13a3b77..798fd4404e 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -233,7 +233,7 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, return ERROR_DNS_NO_MEMORY; } - err = dns_open( servername, DNS_TCP, mem_ctx, &conn ); + err = dns_open_connection( servername, DNS_TCP, mem_ctx, &conn ); if (!ERR_DNS_IS_OK(err)) goto error; if (!(upcaserealm = talloc_strdup(mem_ctx, target_realm))) { -- cgit From c042d06490cc02ec17376c7c057be9f809ca1c6e Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 15 Mar 2007 22:09:03 +0000 Subject: r21848: add a comment about gss_import_name() and when to free the krb5 principal data (This used to be commit 54a114fa7569315a8ad391689ebf5d68ef4a62d4) --- source3/libaddns/dnsgss.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index 798fd4404e..207e86c3ed 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -252,6 +252,11 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, krb5_init_context( &krb_ctx ); krb5_parse_name( krb_ctx, targetname, &host_principal ); + /* don't free the printcap until after you call + gss_release_name() or else you'll get a segv + as the krb5_copy_principal() does a structure + copy and not a deep copy. --jerry*/ + input_name.value = &host_principal; input_name.length = sizeof( host_principal ); @@ -267,8 +272,11 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, err = dns_negotiate_gss_ctx_int(mem_ctx, conn, keyname, targ_name, gss_ctx, srv_type ); - + gss_release_name( &minor, &targ_name ); + + /* now we can feree the principal */ + krb5_free_principal( krb_ctx, host_principal ); krb5_free_context( krb_ctx ); -- cgit From d873858976a2ce70cfa9c790a083ae4fb0ff6b02 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 15 Mar 2007 22:48:30 +0000 Subject: r21851: Obvious typos... (This used to be commit ff886436b739bbb5c00a67de970841205a3f447c) --- source3/libaddns/dnsgss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index 207e86c3ed..8324e6761f 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -252,7 +252,7 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, krb5_init_context( &krb_ctx ); krb5_parse_name( krb_ctx, targetname, &host_principal ); - /* don't free the printcap until after you call + /* don't free the principal until after you call gss_release_name() or else you'll get a segv as the krb5_copy_principal() does a structure copy and not a deep copy. --jerry*/ @@ -275,7 +275,7 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, gss_release_name( &minor, &targ_name ); - /* now we can feree the principal */ + /* now we can free the principal */ krb5_free_principal( krb_ctx, host_principal ); krb5_free_context( krb_ctx ); -- cgit From 674b835241c53af7d31af402bd900e95ac83fcca Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 03:52:17 +0000 Subject: r23799: updated old Franklin Street FSF addresses to new URL (This used to be commit 43cd589773148fe3d243892768ce187604dd0c33) --- source3/libaddns/dnsgss.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index 8324e6761f..9bbad44089 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -19,9 +19,7 @@ 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 + License along with this library; if not, see . */ #include "dns.h" -- cgit From fa78132ab5704618fc31a5d8a024ab7b7dcc81b3 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 13 Sep 2007 16:11:46 +0000 Subject: r25134: Fix Bug #4968 and make dns updates work with heimdal as well (again, gss_import_name() needs to follow the same logic as in the LDAP sasl wrapping (see -r25133). Tested with MIT 1.2.7, 1.3.6, 1.4.3, 1.5.1, 1.6.1 and Heimdal 0.7.2, 1.0, 1.0.1. Guenther (This used to be commit 913fb138aa90a6627ee49b2e92d1bbc73e11f9ea) --- source3/libaddns/dnsgss.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) (limited to 'source3/libaddns/dnsgss.c') diff --git a/source3/libaddns/dnsgss.c b/source3/libaddns/dnsgss.c index 9bbad44089..e7ea041847 100644 --- a/source3/libaddns/dnsgss.c +++ b/source3/libaddns/dnsgss.c @@ -219,11 +219,8 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, gss_name_t targ_name; - krb5_principal host_principal; - krb5_context krb_ctx = NULL; - gss_OID_desc nt_host_oid_desc = - { 10, (char *)"\052\206\110\206\367\022\001\002\002\002" }; + {10, (char *)"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"}; TALLOC_CTX *mem_ctx; @@ -247,23 +244,13 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, goto error; } - krb5_init_context( &krb_ctx ); - krb5_parse_name( krb_ctx, targetname, &host_principal ); - - /* don't free the principal until after you call - gss_release_name() or else you'll get a segv - as the krb5_copy_principal() does a structure - copy and not a deep copy. --jerry*/ - - input_name.value = &host_principal; - input_name.length = sizeof( host_principal ); + input_name.value = targetname; + input_name.length = strlen(targetname); major = gss_import_name( &minor, &input_name, &nt_host_oid_desc, &targ_name ); if (major) { - krb5_free_principal( krb_ctx, host_principal ); - krb5_free_context( krb_ctx ); err = ERROR_DNS_GSS_ERROR; goto error; } @@ -273,11 +260,6 @@ DNS_ERROR dns_negotiate_sec_ctx( const char *target_realm, gss_release_name( &minor, &targ_name ); - /* now we can free the principal */ - - krb5_free_principal( krb_ctx, host_principal ); - krb5_free_context( krb_ctx ); - error: TALLOC_FREE(mem_ctx); -- cgit