]> granicus.if.org Git - pdns/commitdiff
ldap updates
authorBert Hubert <bert.hubert@netherlabs.nl>
Thu, 27 Mar 2003 10:40:40 +0000 (10:40 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Thu, 27 Mar 2003 10:40:40 +0000 (10:40 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@165 d19b8d6e-7fed-0310-83ef-9ca221ded41b

ChangeLog
debian/rules
modules/ldapbackend/ldapbackend.cc
modules/ldapbackend/ldapbackend.hh
modules/ldapbackend/powerldap.hh
pdns/dnspacket.cc
pdns/docs/pdns.sgml
pdns/syncres.cc
pdns/syncres.hh

index 54f63220cfce35040cc26cf6e17861f05219bdae..f3faf0035b1accf6c85f0147bf3145e55f703bc7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+Changes since 2.9.7:
+       - NS queries for zones we are not authoritative about now get their NS
+         records in the authority section
+       - powerldap.hh doesn't need crypt.h (Richard Arends)
+       - can't handle binary labels, print a warning about that
+       - recursor sometimes did very extended negative caching, sometimes for *days*
+
 Changes since 2.9.6:
        * need to do work on ( and ) in zones!
 feat   - added local-query-address (Mark Bergsma)
index 2e0f9487c1824a98aa9470d6d8a5b71b0a074d64..59ca1e7e23c9af3dacdeba614f92afdaa6c15f8f 100755 (executable)
@@ -52,8 +52,10 @@ build-static stamp-build-static:
                --sysconfdir=/etc/powerdns \
                --infodir='$${datadir}/info' \
                --mandir='$${datadir}/man' \
-               --with-modules="mysql gmysql gpgsql pipe pdns xdb" --with-dynmodules="" \
-               --enable-static-binaries --with-pgsql-lib=/opt/postgresql-with-3.2/lib/
+               --with-modules="mysql gmysql gpgsql pipe pdns xdb" \
+               --with-dynmodules="" \
+               --enable-static-binaries --enable-recursor \
+               --with-pgsql-lib=/opt/postgresql-with-3.2/lib/
        make
        touch stamp-build-static
 
@@ -67,7 +69,8 @@ build stamp-build: configure
                --infodir='$${datadir}/info' \
                --mandir='$${datadir}/man' \
                --with-dynmodules="$(backends)" \
-               --with-modules=""
+               --with-modules="" \
+               --enable-recursor
        make
        touch stamp-build
 
@@ -86,6 +89,7 @@ binary-main-prepare:
                --strip-unneeded \
                "$(tmpdir)"/usr/bin/zone2sql \
                "$(tmpdir)"/usr/sbin/pdns_server \
+               "$(tmpdir)"/usr/sbin/pdns_recursor \
                "$(tmpdir)"/usr/bin/pdns_control
        mv "$(tmpdir)"/etc/powerdns/pdns.conf-dist "$(tmpdir)"/etc/powerdns/pdns.conf
 
@@ -163,10 +167,10 @@ binary-indep: binary-doc
 binary-arch: binary-main binary-backend
 
 clean:
-       rm -f debian/files debian/substvars stamp-build stamp-build-static
-       rm -rf "$(tmpdir)" "$(be_tmpdir)"
        -make distclean
        -make -C pdns/docs clean
+       rm -f debian/files debian/substvars stamp-build stamp-build-static
+       rm -rf "$(tmpdir)" "$(be_tmpdir)"
 
 .PHONY: clean build binary binary-arch binary-indep
 .PHONY: binary-doc binary-main binary-backend
index 3f05326b34ac984ac789c737a0a54d072b29b652..4257d628d46fe28eb2fe43e86363af4139abce0d 100644 (file)
@@ -1,8 +1,6 @@
 #include "ldapbackend.hh"
 
-#include <algorithm>
 #include <utility>
-#include <ctype.h> 
 
 static int Toupper(int c)
 {
@@ -14,14 +12,20 @@ LdapBackend::LdapBackend( const string &suffix )
 {
        m_msgid = 0;
        m_qname = "";
-       m_revlookup = 0;
        setArgPrefix( "ldap" + suffix );
 
        L << Logger::Notice << backendname << " Server = " << getArg( "host" ) << ":" << getArg( "port" ) << endl;
 
-       // Initialize connections and pass exeptions to caller
+       try
+       {
        m_pldap = new PowerLDAP( getArg( "host" ), (u_int16_t) atoi( getArg( "port" ).c_str() ) );
        m_pldap->simpleBind( getArg( "binddn" ), getArg( "secret" ) );
+       }
+       catch( LDAPException &e )
+       {
+               L << Logger::Error << backendname << " Ldap connection failed: " << e.what() << endl;
+               throw( AhuException( "Unable to bind to ldap server" ) );
+       }
 
        L << Logger::Notice << backendname << " Ldap connection succeeded" << endl;
 }
@@ -43,40 +47,60 @@ bool LdapBackend::list( int domain_id )
 
 void LdapBackend::lookup( const QType &qtype, const string &qname, DNSPacket *dnspkt, int zoneid )
 {
-       int len = 0;
+       int i, len;
        vector<string> parts;
        string filter, attr, ipaddr;
        char** attributes = attrany;
-       char* attronly[] = { "associatedDomain", NULL, NULL };
+       char* attronly[] = { NULL, NULL };
 
 
        m_qtype = qtype;
        m_qname = qname;
        len = qname.length();
 
-       if( len > 20 && qname.substr( len - 13, 13 ) == ".in-addr.arpa" )
+       if( qname.substr( len - 5, 5 ) == ".arpa" || qname.substr( len - 4, 4 ) == ".int" )
+       {
+               stringtok( parts, qname, "." );
+               if (parts[parts.size()-2] == "ip6" )
+               {
+                       filter = "(aaaaRecord=" + parts[parts.size()-3];
+                       for( i = parts.size() - 4; i >= 0; i-- )   // reverse and cut .ip6.arpa or .ip6.int
+                       {
+                                 filter += ":" + parts[i];
+                       }
+                       filter =  + ")";
+               }
+               else
        {
-               m_revlookup = 1;
-               stringtok( parts, qname.substr( 0, len - 13 ), "." );
                filter = "(aRecord=" + parts[3] + "." + parts[2] + "." + parts[1] + "." + parts[0] + ")";
+               }
+
+               filter = m_pldap->escape( filter );
+               attronly[0] = "associatedDomain";
                attributes = attronly;
        }
        else
        {
-               m_revlookup = 0;
                filter = "(associatedDomain=" + m_pldap->escape( m_qname ) + ")";
-       }
-
        if( qtype.getCode() != QType::ANY )
        {
                attr = qtype.getName() + "Record";
                filter = "(&" + filter + "(" + attr + "=*))";
-               attronly[1] = (char*) attr.c_str();
+                       attronly[0] = (char*) attr.c_str();
                attributes = attronly;
        }
+       }
 
-       // Pass exception if an error occurs
+       try
+       {
        m_msgid = m_pldap->search( getArg("basedn"), filter, (const char**) attributes );
+       }
+       catch( LDAPException &e )
+       {
+               L << Logger::Warning << backendname << " Unable to initiate search: " << e.what() << endl;
+               return;
+       }
+
        L << Logger::Info << backendname << " Search = basedn: " << getArg( "basedn" ) << ", filter: " << filter << ", qtype: " << qtype.getName() << endl;
 }
 
@@ -90,23 +114,19 @@ bool LdapBackend::get( DNSResourceRecord &rr )
        PowerLDAP::sentry_t::iterator attribute;
 
 
-       do
-       {
+Redo:
+
                while( !m_result.empty() )
                {
-                       if( m_revlookup == 1 && m_result.find( "associatedDomain" ) != m_result.end() )
-                       {
-                               m_result["PTRRecord"] = m_result["associatedDomain"];
-                       }
-                       m_result.erase( "associatedDomain" );
-
                        attribute = m_result.begin();
+               if( attribute != m_result.end() && !attribute->second.empty() )
+               {
                        attrname = attribute->first;
                        qstr = attrname.substr( 0, attrname.length() - 6 );   // extract qtype string from ldap attribute name
                        transform( qstr.begin(), qstr.end(), qstr.begin(), &Toupper );
                        qt = QType( const_cast<char*>(qstr.c_str()) );
 
-                       while( !attribute->second.empty() && ( m_qtype.getCode() == QType::ANY ||  m_qtype.getCode() == qt.getCode() ) )
+                       if( m_qtype.getCode() == QType::ANY ||  m_qtype.getCode() == qt.getCode() )
                        {
                                content = attribute->second.back();
                                attribute->second.pop_back();
@@ -126,10 +146,26 @@ bool LdapBackend::get( DNSResourceRecord &rr )
                                L << Logger::Info << backendname << " Record = qname: " << rr.qname << ", qtype: " << (rr.qtype).getName() << ", priority: " << rr.priority << ", content: " << rr.content << endl;
                                return true;
                        }
+               }
                        m_result.erase( attribute );
                }
+
+       try
+       {
+               if( m_pldap->getSearchEntry( m_msgid, m_result ) == true )
+               {
+                               if( m_result.find( "associatedDomain" ) != m_result.end() )
+                               {
+                                       m_result["PTRRecord"] = m_result["associatedDomain"];
+                                       m_result.erase( "associatedDomain" );
+                               }
+                               goto Redo;
+               }
+       }
+       catch( LDAPException &e )
+       {
+               L << Logger::Warning << backendname << " Search failed: " << e.what() << endl;
        }
-       while( m_pldap->getSearchEntry( m_msgid, m_result ) );
 
        return false;
 }
index d34d3190d59a94649b00e46f7b8668205da5259e..90c95b3a185999830141ef6ebb5957176c394d7c 100644 (file)
@@ -1,8 +1,10 @@
+#include <algorithm>
 #include <sstream>
 #include <utility>
 #include <string>
 #include <ldap.h>
 #include <stdlib.h>
+#include <ctype.h>
 #include <unistd.h>
 #include <pdns/dns.hh>
 #include <pdns/utility.hh>
@@ -24,7 +26,6 @@ using namespace std;
 static string backendname="[LdapBackend]";
 
 static char* attrany[] = {
-       "associatedDomain",
        "ARecord",
        "NSRecord",
        "CNAMERecord",
@@ -47,8 +48,6 @@ class LdapBackend : public DNSBackend
 private:
 
        int m_msgid;
-        int m_revlookup;
-  
        QType m_qtype;
        string m_qname;
        PowerLDAP* m_pldap;
index 611f488d536db94aaece0ff9c38740391f19d356..116dea8fce8b92b2cf149c7c06aeee0db0d16ed0 100644 (file)
@@ -2,7 +2,6 @@
 #define POWERLDAP_HH
 #include <map>
 #include <vector>
-#include <crypt.h>
 #include <exception>
 #include <stdexcept>
 #include <string>
index 3ab1c39c0e903f3b93bd74a8fe5cef9f2330fc3d..39fdb4d575272ce821f08d7b9a5f0a3c05b5f249 100644 (file)
@@ -16,7 +16,7 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
-// $Id: dnspacket.cc,v 1.19 2003/03/20 13:29:29 ahu Exp $
+// $Id: dnspacket.cc,v 1.20 2003/03/27 10:40:40 ahu Exp $
 #include "utility.hh"
 #include <cstdio>
 
@@ -102,31 +102,34 @@ int DNSPacket::expand(const unsigned char *begin, const unsigned char *end, stri
 
   while((n=*(unsigned char *)p++)) {
     char tmp[256];
-      if((n & 0xc0) == 0xc0 ) { 
-       unsigned int labelOffset=(n&~0xc0)*256+ (int)*(unsigned char *)p;
-       expand((unsigned char *)stringbuffer.c_str()+labelOffset,end,expanded,depth++);
-       return 1+p-begin;
-      }
-
-      if(p+n>=end) { // this is a bogus packet, references beyond the end of the buffer
-       throw AhuException("Label claims to be longer than packet");
-      }
-      strncpy((char *)tmp,(const char *)p,n);
-
-      if(*(p+n)) { // add a ., except at the end
-         tmp[n]='.';
-         tmp[n+1]=0;
-      }
-      else
-       tmp[n]=0;
+    if(n==0x41)
+       throw AhuException("unable to expand binary label, generally caused by deprecated IPv6 reverse lookups");
 
-      expanded+=tmp;
+    if((n & 0xc0) == 0xc0 ) { 
+       unsigned int labelOffset=(n&~0xc0)*256+ (int)*(unsigned char *)p;
+       expand((unsigned char *)stringbuffer.c_str()+labelOffset,end,expanded,depth++);
+       return 1+p-begin;
+    }
 
-      p+=n;
+    if(p+n>=end) { // this is a bogus packet, references beyond the end of the buffer
+       throw AhuException("Label claims to be longer than packet");
     }
+    strncpy((char *)tmp,(const char *)p,n);
     
+    if(*(p+n)) { // add a ., except at the end
+       tmp[n]='.';
+       tmp[n+1]=0;
+    }
+    else
+       tmp[n]=0;
+    
+    expanded+=tmp;
+    
+    p+=n;
+  }
+  
   // lowercase(qdomain); (why was this?)
-
+  
   return p-begin;
 
 }
@@ -143,7 +146,7 @@ int DNSPacket::getq()
     return expand(orig,end,qdomain);
   }
   catch(AhuException &ae) {
-    L<<Logger::Error<<"On retrieving question of packet, encountered error: "<<ae.reason<<endl;
+     L<<Logger::Error<<"On retrieving question of packet from "<<getRemote()<<", encountered error: "<<ae.reason<<endl;
   }
   return -1;
 }
index f66899a3f653abd0f5d3c5aebfc3550bc7ddf305..9397d10394625c4112ada83bb5054f66aab679fa 100644 (file)
@@ -11,7 +11,7 @@
       </affiliation>
     </author>
     
-    <PubDate>v2.1 $Date: 2003/03/20 12:53:44 $</PubDate>
+    <PubDate>v2.1 $Date: 2003/03/27 10:40:40 $</PubDate>
     
     <Abstract>
        <para>  
@@ -4379,6 +4379,14 @@ local0.err                        /var/log/pdns.err
              </para>
            </listitem>
          </varlistentry>
+         <varlistentry>
+           <term>config-dir</term>
+           <listitem>
+             <para>
+               Directory where the configuration file can be found.
+             </para>
+           </listitem>
+         </varlistentry>
          <varlistentry>
            <term>daemon</term>
            <listitem>
@@ -4405,6 +4413,14 @@ local0.err                        /var/log/pdns.err
              </para>
            </listitem>
          </varlistentry>
+         <varlistentry>
+           <term>quiet</term>
+           <listitem>
+             <para>
+               Don't log queries.
+             </para>
+           </listitem>
+         </varlistentry>
          <varlistentry>
            <term>trace</term>
            <listitem>
index 8b55f5c7e319c1d1790b3c177297fc065dfc3ea4..3d3fc01041c28e9fcc214932e2172d5bcecde98d 100644 (file)
@@ -33,7 +33,7 @@
 #include "arguments.hh"
 #include "lwres.hh"
 
-map<string,string> SyncRes::s_negcache;
+map<string,NegCacheEntry> SyncRes::s_negcache;    
 unsigned int SyncRes::s_queries;
 unsigned int SyncRes::s_outqueries;
 unsigned int SyncRes::s_throttledqueries;
@@ -188,6 +188,9 @@ bool SyncRes::doCNAMECacheCheck(const string &qname, const QType &qtype, vector<
   return false;
 }
 
+
+
+
 bool SyncRes::doCacheCheck(const string &qname, const QType &qtype, vector<DNSResourceRecord>&ret, int depth, int &res)
 {
   bool giveNegative=false;
@@ -196,29 +199,45 @@ bool SyncRes::doCacheCheck(const string &qname, const QType &qtype, vector<DNSRe
 
   string sqname(qname);
   QType sqt(qtype);
+  u_int32_t sttl=0;
 
   if(s_negcache.count(toLower(qname))) {
     res=0;
-    map<string,string>::const_iterator ni=s_negcache.find(toLower(qname));
+    map<string,NegCacheEntry>::const_iterator ni=s_negcache.find(toLower(qname));
+    if(time(0) < ni->second.ttd) {
+      sttl=ni->second.ttd-time(0);
+      LOG<<prefix<<qname<<": Entire record '"<<toLower(qname)<<"', is negatively cached for another "<<sttl<<" seconds"<<endl;
+      res=RCode::NXDomain; 
+      giveNegative=true;
+      sqname=ni->second.name;
+      sqt="SOA";
 
-    LOG<<prefix<<qname<<": Entire record '"<<toLower(qname)<<"', is negatively cached "<<endl;
-    res=RCode::NXDomain; 
-    giveNegative=true;
-    sqname=ni->second;
-    sqt="SOA";
+    }
+    else {
+      LOG<<prefix<<qname<<": Entire record '"<<toLower(qname)<<"' was negatively cached, but entry expired"<<endl;
+      s_negcache.erase(toLower(qname));
+    }
   }
-  else {
+
+  if(!giveNegative) { // let's try some more
     tuple=toLower(qname)+"|"+qtype.getName();
     LOG<<prefix<<qname<<": Looking for direct cache hit of '"<<tuple<<"', "<<s_negcache.count(tuple)<<endl;
 
     res=0;
-    map<string,string>::const_iterator ni=s_negcache.find(tuple);
+    map<string,NegCacheEntry>::const_iterator ni=s_negcache.find(tuple);
     if(ni!=s_negcache.end()) {
-      LOG<<prefix<<qname<<": "<<qtype.getName()<<" is negatively cached, will return immediately if we still have SOA ("<<ni->second<<") to prove it"<<endl;
-      res=RCode::NoError; // only this record doesn't exist
-      giveNegative=true;
-      sqname=ni->second;
-      sqt="SOA";
+      if(time(0) < ni->second.ttd) {
+       sttl=ni->second.ttd-time(0);
+       LOG<<prefix<<qname<<": "<<qtype.getName()<<" is negatively cached for another "<<sttl<<" seconds"<<endl;
+       res=RCode::NoError; // only this record doesn't exist
+       giveNegative=true;
+       sqname=ni->second.name;
+       sqt="SOA";
+      }
+      else {
+       LOG<<prefix<<qname<<": "<<qtype.getName()<<" was negatively cached, but entry expired"<<endl;
+       s_negcache.erase(toLower(tuple));
+      }
     }
   }
 
@@ -231,8 +250,10 @@ bool SyncRes::doCacheCheck(const string &qname, const QType &qtype, vector<DNSRe
       if(j->ttl>(unsigned int)time(0)) {
        DNSResourceRecord rr=*j;
        rr.ttl-=time(0);
-       if(giveNegative)
+       if(giveNegative) {
          rr.d_place=DNSResourceRecord::AUTHORITY;
+         rr.ttl=sttl;
+       }
        ret.push_back(rr);
        LOG<<"[ttl="<<rr.ttl<<"] ";
        found=true;
@@ -379,7 +400,10 @@ int SyncRes::doResolveAt(set<string> nameservers, string auth, const string &qna
          LOG<<prefix<<qname<<": got negative caching indication for RECORD '"<<toLower(qname)+"'"<<endl;
          ret.push_back(*i);
 
-         s_negcache[toLower(qname)]=i->qname;
+         NegCacheEntry ne;
+         ne.name=i->qname;
+         ne.ttd=time(0)+i->ttl;
+         s_negcache[toLower(qname)]=ne;
          negindic=true;
        }
        else if(i->d_place==DNSResourceRecord::ANSWER && i->qname==qname && i->qtype.getCode()==QType::CNAME && (!(qtype==QType(QType::CNAME)))) {
@@ -406,8 +430,11 @@ int SyncRes::doResolveAt(set<string> nameservers, string auth, const string &qna
           d_lwr.d_rcode==RCode::NoError) {
          LOG<<prefix<<qname<<": got negative caching indication for '"<<toLower(qname)+"|"+i->qtype.getName()+"'"<<endl;
          ret.push_back(*i);
-
-         s_negcache[toLower(qname)+"|"+qtype.getName()]=i->qname;
+         
+         NegCacheEntry ne;
+         ne.name=i->qname;
+         ne.ttd=time(0)+i->ttl;
+         s_negcache[toLower(qname)+"|"+qtype.getName()]=ne;
          negindic=true;
        }
       }
index af767dc3ef3141c12b57a7a2261a070d31273f92..0b2948c57ae89f1a8211dd10433ebb3a8b01e0a9 100644 (file)
 void replaceCache(const string &qname, const QType &qt, const set<DNSResourceRecord>& content);
 int getCache(const string &qname, const QType& qt, set<DNSResourceRecord>* res=0);
 
+struct NegCacheEntry
+{
+  string name;
+  time_t ttd;
+};
 
 template<class Thing> class Throttle
 {
@@ -80,7 +85,7 @@ public:
   static unsigned int s_outqueries;
   unsigned int d_outqueries;
   unsigned int d_throttledqueries;
-  static map<string,string> s_negcache;    
+  static map<string,NegCacheEntry> s_negcache;    
   static Throttle<string> s_throttle;
 private:
   struct GetBestNSAnswer;