From: Grégory Oestreicher Date: Wed, 12 Apr 2017 19:26:22 +0000 (+0200) Subject: Various Kerberos improvments X-Git-Tag: dnsdist-1.3.1~167^2~9 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=4a1841c523f4f13fdf73991bc3287da7d9bab1f5;p=thirdparty%2Fpdns.git Various Kerberos improvments Move Kerberos data in member variables Use a temporary Kerberos credentials cache when getting the ticket Add the Kerberos realm in the ticket request --- diff --git a/modules/ldapbackend/ldapauthenticator.cc b/modules/ldapbackend/ldapauthenticator.cc index 77577ad475..c4bc6d8de5 100644 --- a/modules/ldapbackend/ldapauthenticator.cc +++ b/modules/ldapbackend/ldapauthenticator.cc @@ -17,7 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ -#include #include #include "ldapauthenticator_p.hh" #include "ldaputils.hh" @@ -85,6 +84,29 @@ static int ldapGssapiAuthenticatorSaslInteractCallback( LDAP *conn, unsigned fla LdapGssapiAuthenticator::LdapGssapiAuthenticator( const std::string& kt, const std::string &ccache, int tmout ) : logPrefix( "[LDAP GSSAPI] " ), keytabFile( kt ), cCacheFile( ccache ), timeout( tmout ) { + krb5_error_code code; + + if ( ( code = krb5_init_context( &m_context ) ) != 0 ) + throw PDNSException( logPrefix + std::string( "Failed to initialize krb5 context" ) ); + + // Locate the credentials cache file + if ( !cCacheFile.empty() ) { + std::string cCacheStr( "FILE:" + cCacheFile ); + code = krb5_cc_resolve( m_context, cCacheStr.c_str(), &m_ccache ); + } + else { + code = krb5_cc_default( m_context, &m_ccache ); + } + + if ( code != 0 ) + throw PDNSException( logPrefix + + std::string( "krb5 error when locating the credentials cache file: " ) + + std::string( krb5_get_error_message( m_context, code ) ) ); +} + +LdapGssapiAuthenticator::~LdapGssapiAuthenticator() +{ + krb5_free_context( m_context ); } bool LdapGssapiAuthenticator::authenticate( LDAP *conn ) @@ -117,7 +139,7 @@ int LdapGssapiAuthenticator::attemptAuth( LDAP *conn ) { // Create SASL defaults SaslDefaults defaults; - char *ldapOption = 0; + char *ldapOption = nullptr; ldap_get_option( conn, LDAP_OPT_X_SASL_MECH, ldapOption ); if ( !ldapOption ) @@ -125,21 +147,25 @@ int LdapGssapiAuthenticator::attemptAuth( LDAP *conn ) else defaults.mech = std::string( ldapOption ); ldap_memfree( ldapOption ); + ldapOption = nullptr; ldap_get_option( conn, LDAP_OPT_X_SASL_REALM, ldapOption ); if ( ldapOption ) defaults.realm = std::string( ldapOption ); ldap_memfree( ldapOption ); + ldapOption = nullptr; ldap_get_option( conn, LDAP_OPT_X_SASL_AUTHCID, ldapOption ); if ( ldapOption ) defaults.authcid = std::string( ldapOption ); ldap_memfree( ldapOption ); + ldapOption = nullptr; ldap_get_option( conn, LDAP_OPT_X_SASL_AUTHZID, ldapOption ); if ( ldapOption ) defaults.authzid = std::string( ldapOption ); ldap_memfree( ldapOption ); + ldapOption = nullptr; // And now try to bind int rc = ldap_sasl_interactive_bind_s( conn, "", defaults.mech.c_str(), @@ -163,100 +189,108 @@ int LdapGssapiAuthenticator::attemptAuth( LDAP *conn ) int LdapGssapiAuthenticator::updateTgt() { krb5_error_code code; - krb5_context context; krb5_creds credentials; krb5_keytab keytab; krb5_principal principal; - krb5_ccache ccache; krb5_get_init_creds_opt *options; - if ( ( code = krb5_init_context( &context ) ) != 0 ) { - g_log< #include "ldapauthenticator.hh" #ifndef LDAPAUTHENTICATOR_P_HH @@ -47,6 +48,9 @@ class LdapGssapiAuthenticator : public LdapAuthenticator std::string cCacheFile; int timeout; std::string lastError; + + krb5_context m_context; + krb5_ccache m_ccache; struct SaslDefaults { std::string mech; @@ -60,6 +64,7 @@ class LdapGssapiAuthenticator : public LdapAuthenticator public: LdapGssapiAuthenticator( const std::string &keytab, const std::string &credsCache, int timeout ); + ~LdapGssapiAuthenticator(); virtual bool authenticate( LDAP *conn ); virtual std::string getError() const; };