From: Grégory Oestreicher Date: Wed, 14 Sep 2016 17:04:35 +0000 (+0200) Subject: Add the LDAP simple authenticator. X-Git-Tag: rec-4.1.0-alpha1~170^2~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0163a3182e439d4d15f8141e136936216624043c;p=thirdparty%2Fpdns.git Add the LDAP simple authenticator. All authentication work will be delegated to an implementation of the LdapAuthenticator pure abstract class. The first authenticator is here to support the classical password bind. --- diff --git a/m4/pdns_check_ldap.m4 b/m4/pdns_check_ldap.m4 index b6f9d0ea33..ddd1c88431 100644 --- a/m4/pdns_check_ldap.m4 +++ b/m4/pdns_check_ldap.m4 @@ -36,4 +36,19 @@ AC_DEFUN([PDNS_CHECK_LDAP],[ ) AC_ARG_VAR([LDAP_LIBS], [linker flags for openldap]) + + AC_CHECK_HEADERS([krb5.h], + [], + [AC_MSG_ERROR([Kerberos header (krb5.h) not found])] + ) + + AC_ARG_VAR([KRB5_LIBS], [linker flag to add Kerberos 5 libraries]) + + AC_CHECK_LIB([krb5], [krb5_init_context], + [ + KRB5_LIBS="-lkrb5" + ] + ) + + AC_CHECK_FUNCS([krb5_get_init_creds_opt_set_default_flags]) ]) diff --git a/modules/ldapbackend/Makefile.am b/modules/ldapbackend/Makefile.am index e6f9cc6664..93a6713242 100644 --- a/modules/ldapbackend/Makefile.am +++ b/modules/ldapbackend/Makefile.am @@ -6,7 +6,8 @@ libldapbackend_la_SOURCES = \ ldapbackend.cc ldapbackend.hh \ powerldap.cc powerldap.hh \ utils.hh exceptions.hh \ - ldaputils.hh ldaputils.cc + ldaputils.hh ldaputils.cc \ + ldapauthenticator.hh ldapauthenticator_p.hh ldapauthenticator.cc libldapbackend_la_LDFLAGS = -module -avoid-version -libldapbackend_la_LIBADD = $(LDAP_LIBS) +libldapbackend_la_LIBADD = $(LDAP_LIBS) $(KRB5_LIBS) diff --git a/modules/ldapbackend/OBJECTFILES b/modules/ldapbackend/OBJECTFILES index faad6e569b..0f75836884 100644 --- a/modules/ldapbackend/OBJECTFILES +++ b/modules/ldapbackend/OBJECTFILES @@ -1 +1 @@ -ldapbackend.lo powerldap.lo ldaputils.lo +ldapbackend.lo powerldap.lo ldaputils.lo ldapauthenticator.lo diff --git a/modules/ldapbackend/OBJECTLIBS b/modules/ldapbackend/OBJECTLIBS index ab9c9d9c82..f296c5a32f 100644 --- a/modules/ldapbackend/OBJECTLIBS +++ b/modules/ldapbackend/OBJECTLIBS @@ -1 +1 @@ -$(LDAP_LIBS) +$(LDAP_LIBS) $(KRB5_LIBS) diff --git a/modules/ldapbackend/ldapauthenticator.cc b/modules/ldapbackend/ldapauthenticator.cc new file mode 100644 index 0000000000..7510a5df9b --- /dev/null +++ b/modules/ldapbackend/ldapauthenticator.cc @@ -0,0 +1,71 @@ +/* + * PowerDNS LDAP Backend + * Copyright (C) 2011 Grégory Oestreicher + * Copyright (C) 2003-2007 Norbert Sendetzky + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include "ldapauthenticator_p.hh" +#include "ldaputils.hh" + +/***************************** + * + * LdapSimpleAuthenticator + * + ****************************/ + +LdapSimpleAuthenticator::LdapSimpleAuthenticator( const std::string& dn, const std::string& pw, int tmout ) + : binddn( dn ), bindpw( pw ), timeout( tmout ) +{ +} + +bool LdapSimpleAuthenticator::authenticate( LDAP *conn ) +{ + int msgid; + +#ifdef HAVE_LDAP_SASL_BIND + int rc; + struct berval passwd; + + passwd.bv_val = (char *)bindpw.c_str(); + passwd.bv_len = strlen( passwd.bv_val ); + + if( ( rc = ldap_sasl_bind( conn, binddn.c_str(), LDAP_SASL_SIMPLE, &passwd, NULL, NULL, &msgid ) ) != LDAP_SUCCESS ) + { + fillLastError( conn, rc ); + return false; + } +#else + if( ( msgid = ldap_bind( conn, binddn.c_str(), bindpw.c_str(), LDAP_AUTH_SIMPLE ) ) == -1 ) + { + fillLastError( conn, msgid ); + return false; + } +#endif + + ldapWaitResult( conn, msgid, timeout, NULL ); + return true; +} + +std::string LdapSimpleAuthenticator::getError() const +{ + return lastError; +} + +void LdapSimpleAuthenticator::fillLastError( LDAP* conn, int code ) +{ + lastError = ldapGetError( conn, code ); +} diff --git a/modules/ldapbackend/ldapauthenticator.hh b/modules/ldapbackend/ldapauthenticator.hh new file mode 100644 index 0000000000..c2061c857f --- /dev/null +++ b/modules/ldapbackend/ldapauthenticator.hh @@ -0,0 +1,37 @@ +/* + * PowerDNS LDAP Backend + * Copyright (C) 2011 Grégory Oestreicher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifndef LDAPAUTHENTICATOR_HH +#define LDAPAUTHENTICATOR_HH + +class LdapAuthenticator +{ +public: + virtual ~LdapAuthenticator() {} + virtual bool authenticate( LDAP *connection ) = 0; + virtual std::string getError() const = 0; +}; + +#endif // LDAPAUTHENTICATOR_HH diff --git a/modules/ldapbackend/ldapauthenticator_p.hh b/modules/ldapbackend/ldapauthenticator_p.hh new file mode 100644 index 0000000000..0168cb2050 --- /dev/null +++ b/modules/ldapbackend/ldapauthenticator_p.hh @@ -0,0 +1,39 @@ +/* + * PowerDNS LDAP Backend + * Copyright (C) 2011 Grégory Oestreicher + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "ldapauthenticator.hh" + +#ifndef LDAPAUTHENTICATOR_P_HH +#define LDAPAUTHENTICATOR_P_HH + +class LdapSimpleAuthenticator : public LdapAuthenticator +{ + std::string binddn; + std::string bindpw; + int timeout; + std::string lastError; + + void fillLastError( LDAP *conn, int code ); + +public: + LdapSimpleAuthenticator( const std::string &dn, const std::string &pw, int timeout ); + virtual bool authenticate( LDAP *conn ); + virtual std::string getError() const; +}; + +#endif // LDAPAUTHENTICATOR_P_HH diff --git a/modules/ldapbackend/ldapbackend.cc b/modules/ldapbackend/ldapbackend.cc index e920cafb76..a14c81bd52 100644 --- a/modules/ldapbackend/ldapbackend.cc +++ b/modules/ldapbackend/ldapbackend.cc @@ -24,6 +24,7 @@ #include "config.h" #endif #include "exceptions.hh" +#include "ldapauthenticator_p.hh" #include "ldapbackend.hh" unsigned int ldap_host_index = 0; @@ -40,6 +41,7 @@ LdapBackend::LdapBackend( const string &suffix ) m_msgid = 0; m_qname.clear(); m_pldap = NULL; + m_authenticator = NULL; m_ttl = 0; m_axfrqlen = 0; m_last_modified = 0; @@ -80,6 +82,8 @@ LdapBackend::LdapBackend( const string &suffix ) m_pldap = new PowerLDAP( hoststr.c_str(), LDAP_PORT, mustDo( "starttls" ) ); m_pldap->setOption( LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS ); m_pldap->bind( getArg( "binddn" ), getArg( "secret" ), LDAP_AUTH_SIMPLE, getArgAsNum( "timeout" ) ); + m_authenticator = new LdapSimpleAuthenticator( getArg( "binddn" ), getArg( "secret" ), getArgAsNum( "timeout" ) ); + m_pldap->bind( m_authenticator ); L << Logger::Notice << m_myname << " Ldap connection succeeded" << endl; return; @@ -105,12 +109,9 @@ LdapBackend::LdapBackend( const string &suffix ) LdapBackend::~LdapBackend() { - if( m_pldap != NULL ) { delete( m_pldap ); } - try { - L << Logger::Notice << m_myname << " Ldap connection closed" << endl; - } - catch (...) { - } + delete( m_pldap ); + delete( m_authenticator ); + L << Logger::Notice << m_myname << " Ldap connection closed" << endl; } diff --git a/modules/ldapbackend/ldapbackend.hh b/modules/ldapbackend/ldapbackend.hh index 0b12bb459d..b634b3073f 100644 --- a/modules/ldapbackend/ldapbackend.hh +++ b/modules/ldapbackend/ldapbackend.hh @@ -45,7 +45,7 @@ using std::string; using std::vector; - +class LdapAuthenticator; /* * Known DNS RR types @@ -107,6 +107,7 @@ class LdapBackend : public DNSBackend string m_myname; DNSName m_qname; PowerLDAP* m_pldap; + LdapAuthenticator *m_authenticator; PowerLDAP::sentry_t m_result; PowerLDAP::sentry_t::iterator m_attribute; vector::iterator m_value; diff --git a/modules/ldapbackend/powerldap.cc b/modules/ldapbackend/powerldap.cc index 045702f086..f6c48c39f6 100644 --- a/modules/ldapbackend/powerldap.cc +++ b/modules/ldapbackend/powerldap.cc @@ -24,6 +24,7 @@ #include "config.h" #endif #include "exceptions.hh" +#include "ldapauthenticator.hh" #include "ldaputils.hh" #include "powerldap.hh" #include "pdns/misc.hh" @@ -109,6 +110,13 @@ void PowerLDAP::getOption( int option, int *value ) } +void PowerLDAP::bind( LdapAuthenticator* authenticator ) +{ + if ( !authenticator->authenticate( d_ld ) ) + throw LDAPException( "Failed to bind to LDAP server: " + authenticator->getError() ); +} + + void PowerLDAP::bind( const string& ldapbinddn, const string& ldapsecret, int method, int timeout ) { int msgid; @@ -167,7 +175,7 @@ int PowerLDAP::search( const string& base, int scope, const string& filter, cons int PowerLDAP::waitResult( int msgid, int timeout, LDAPMessage** result ) { try { - ldapWaitResult( d_ld, msgid, timeout, result ); + return ldapWaitResult( d_ld, msgid, timeout, result ); } catch ( LDAPException &e ) { ensureConnect(); diff --git a/modules/ldapbackend/powerldap.hh b/modules/ldapbackend/powerldap.hh index c7f0abfa31..73014d1b60 100644 --- a/modules/ldapbackend/powerldap.hh +++ b/modules/ldapbackend/powerldap.hh @@ -39,6 +39,8 @@ using std::map; using std::string; using std::vector; +class LdapAuthenticator; + class PowerLDAP { LDAP* d_ld; @@ -60,6 +62,7 @@ public: void getOption( int option, int* value ); void setOption( int option, int value ); + void bind( LdapAuthenticator *authenticator ); void bind( const string& ldapbinddn = "", const string& ldapsecret = "", int method = LDAP_AUTH_SIMPLE, int timeout = 5 ); void simpleBind( const string& ldapbinddn = "", const string& ldapsecret = "" ); int search( const string& base, int scope, const string& filter, const char** attr = 0 );