]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Add the LDAP simple authenticator.
authorGrégory Oestreicher <greg@kamago.net>
Wed, 14 Sep 2016 17:04:35 +0000 (19:04 +0200)
committerGrégory Oestreicher <greg@kamago.net>
Tue, 28 Feb 2017 21:34:29 +0000 (22:34 +0100)
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.

m4/pdns_check_ldap.m4
modules/ldapbackend/Makefile.am
modules/ldapbackend/OBJECTFILES
modules/ldapbackend/OBJECTLIBS
modules/ldapbackend/ldapauthenticator.cc [new file with mode: 0644]
modules/ldapbackend/ldapauthenticator.hh [new file with mode: 0644]
modules/ldapbackend/ldapauthenticator_p.hh [new file with mode: 0644]
modules/ldapbackend/ldapbackend.cc
modules/ldapbackend/ldapbackend.hh
modules/ldapbackend/powerldap.cc
modules/ldapbackend/powerldap.hh

index b6f9d0ea33205b494b35c927a002396361534bdc..ddd1c884316af6bffc220208836181a341790822 100644 (file)
@@ -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])
 ])
index e6f9cc66645831851c467c3d98be3c1de2f70ebd..93a6713242ad887ef86fe23d76a69ee80c703e59 100644 (file)
@@ -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)
index faad6e569b881d15d8edabcfc02faaa783543636..0f758368845a76ba7a048b3968a4bd3bb7ba7c8a 100644 (file)
@@ -1 +1 @@
-ldapbackend.lo powerldap.lo ldaputils.lo
+ldapbackend.lo powerldap.lo ldaputils.lo ldapauthenticator.lo
index ab9c9d9c82163b9997ee0cfea496eab00cdcd5a9..f296c5a32f016f3a25a6e4edae0ead458b720824 100644 (file)
@@ -1 +1 @@
-$(LDAP_LIBS)
+$(LDAP_LIBS) $(KRB5_LIBS)
diff --git a/modules/ldapbackend/ldapauthenticator.cc b/modules/ldapbackend/ldapauthenticator.cc
new file mode 100644 (file)
index 0000000..7510a5d
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  PowerDNS LDAP Backend
+ *  Copyright (C) 2011 Grégory Oestreicher <greg@kamago.net>
+ *  Copyright (C) 2003-2007 Norbert Sendetzky <norbert@linuxnetworks.de>
+ *
+ *  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 <pdns/logger.hh>
+#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 (file)
index 0000000..c2061c8
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ *  PowerDNS LDAP Backend
+ *  Copyright (C) 2011 Grégory Oestreicher <greg@kamago.net>
+ *
+ *  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 <ldap.h>
+#include <string>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#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 (file)
index 0000000..0168cb2
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ *  PowerDNS LDAP Backend
+ *  Copyright (C) 2011 Grégory Oestreicher <greg@kamago.net>
+ *
+ *  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
index e920cafb76aad6ce4ed3e16388f1b846f6b2a040..a14c81bd52fd939e3b9cb27a9e9b1d4ce78f4fe3 100644 (file)
@@ -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;
 }
 
 
index 0b12bb459d74280658fb394cc01404babf511875..b634b3073f13ba35119d168ac3ece1a5c894a847 100644 (file)
@@ -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<string>::iterator m_value;
index 045702f086269d22c2192ad67df8d7bc137aaba8..f6c48c39f61a21f7f4d8af88ea78f0d9a293bf92 100644 (file)
@@ -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();
index c7f0abfa3118ca277cbb7c0189f0cc4613b7c12b..73014d1b60cf5b55ab7128cdcb3c53a67189b21e 100644 (file)
@@ -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 );