ldap2dns-0.3.1/0040775000100100010010000000000007526217223012170 5ustar jriefjriefldap2dns-0.3.1/webadmin/0040775000100100010010000000000007526217166013764 5ustar jriefjriefldap2dns-0.3.1/webadmin/config.inc0100664000100100010010000000340207526217166015720 0ustar jriefjrief "", "dnsserial" => "", "dnsclass" => "IN", "dnstype" => "SOA", "dnsexpire" => "604800", "dnsretry" => "3600", "dnsminimum" => "86400", "dnsrefresh" => "10800", "dnsttl" => "3600", "dnszonemaster" => "ns1.company.com.", "dnsadminmailbox" => "hostmaster.company.com.", ); $ZONE_ENTRY = array( array("cn"=>"NS1:", "objectclass"=>"dnsrrset", "dnstype"=>"NS", "dnsclass"=>"IN", "dnsttl"=>"3600", "dnscname"=>"ns1.company.com."), array("cn"=>"NS2:", "objectclass"=>"dnsrrset", "dnstype"=>"NS", "dnsclass"=>"IN", "dnsttl"=>"3600", "dnscname"=>"ns2.company.com."), ); #################### whois configuration #################### $WHOISSERVERS = array( "at"=>"whois.nic.at", "de"=>"whois.denic.de", "ch"=>"whois.nic.ch", "com"=>"whois.networksolutions.com", "net"=>"whois.networksolutions.com", "org"=>"whois.networksolutions.com", "be"=>"whois.dns.be", "cz"=>"whois.nic.cz", "fr"=>"whois.nic.fr", "hu"=>"whois.nic.hu", "it"=>"whois.nic.it", "dk"=>"whois.dk-hostmaster.dk", "li"=>"whois.nic.li", "lu"=>"whois.dns.lu", "cc"=>"whois.nic.cc", "uk"=>"whois.nic.uk" ); ?> ldap2dns-0.3.1/webadmin/footer.inc0100664000100100010010000000002507504104553015736 0ustar jriefjrief
ldap2dns-0.3.1/webadmin/framesets.inc0100664000100100010010000000057507526202525016445 0ustar jriefjriefDNS Zone Admin You need a frame capable browser ldap2dns-0.3.1/webadmin/icons/0040775000100100010010000000000007526176540015077 5ustar jriefjriefldap2dns-0.3.1/webadmin/icons/branch-cont.gif0100664000100100010010000000152107504105012017736 0ustar jriefjriefGIF89aїkk”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,@.HА Сƒ*\ШАЁУ‡# ‘bD‹)jАcAA6ЩфР€;ldap2dns-0.3.1/webadmin/icons/branch-end.gif0100664000100100010010000000151307504105012017542 0ustar jriefjriefGIF89aїkk”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,@(HА Сƒ*\ШАЁУ‡# ‘bD‹)jАЃФ !;ldap2dns-0.3.1/webadmin/icons/folder-closed.gif0100664000100100010010000000156707504105012020274 0ustar jriefjriefGIF89aїccckЕџ””cЮЮcчоkїя{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,T@p€$Р€A… JœH№р3jЬ(РХ CŠйёуШ“% œDщQхJ‘)_Тl)3dЬšJRмй€ЯŸ@ƒ€HДЈбЃE;ldap2dns-0.3.1/webadmin/icons/folder-open.gif0100664000100100010010000000161707504105012017760 0ustar jriefjriefGIF89aїccckk”kЕџ””cЮЮcЮЮ”чоkїя{џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,l$@Р ` Ёƒ 2tиА`Сƒ )jt8РТ CŠ` #(SЊ$`€IbЪ”Щв%€“3sЈщЇЮ˜<Тќ €GЁDwhБiСЃŒJ:5ЂРVГjЕŠ5b@;ldap2dns-0.3.1/webadmin/icons/img-blank.gif0100664000100100010010000000150207504105012017400 0ustar jriefjriefGIF89aїkk”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,@HА Сƒ*\ШАЁУ‡#JœHБЂХ‹ ;ldap2dns-0.3.1/webadmin/icons/img-vert-line.gif0100664000100100010010000000151407504105012020221 0ustar jriefjriefGIF89aїkk”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,@)HА Сƒ*\ШАЁУ‡# ‘bD‹1>дшcC A ;ldap2dns-0.3.1/webadmin/icons/minus-cont.gif0100664000100100010010000000154307504105012017640 0ustar jriefjriefGIF89aїkk”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,@@HА A&<ˆP!У‡#B\XЂCƒ%j$˜ёa€ ANМШ0!€“'$\Љ’#I…!Cnь(‘цР€;ldap2dns-0.3.1/webadmin/icons/minus-end.gif0100664000100100010010000000154007504105012017440 0ustar jriefjriefGIF89aїkk”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,@=HА A&<ˆP!У‡#B\XЂCƒ%j$˜ёa€ ANМШ0!€“'$\Љ’#I…!Cnœ93 ;ldap2dns-0.3.1/webadmin/icons/plus-cont.gif0100664000100100010010000000155007504105012017466 0ustar jriefjriefGIF89aїkk”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,@EHА A˜№ Тƒ JœHбaФ…%F$ИБЂGŽˆ9rтE†&XЙR@Т—.A ФS#I’!?Ъt;ldap2dns-0.3.1/webadmin/icons/plus-end.gif0100664000100100010010000000154707504105012017277 0ustar jriefjriefGIF89aїkk”џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,@DHА A˜№ Тƒ JœHбaФ…%F$ИБЂGŽˆ9rтE†&XЙR@Т—.A ФS#I’sц ;ldap2dns-0.3.1/webadmin/icons/zone_forb.gif0100664000100100010010000000171407504105012017527 0ustar jriefjriefGIF89aїџ)cџ”џ)Юџ)џџЮџџччжџїяЪџ%%ф**џ<<џLLзIIэppюttџўўџџџоооННН”””„„„sssRRRРРР€ьXл#@€0шЇqЅwАђ8ЄwXл#PŒрх˜LВw`ѓ”qдwшGгwџџџџdшЪ‚ЄwшxЄw:yЄw0ш`шEР)ˆwxEа!8шєщЇ‹w*ˆwџџџџъОБŒwx `8Вw€ь<‚Єw€ьмк#@к#АэЅw<РFC:\TEMP\GLOBE_ROT.GIFщ3)ˆwш9ршˆ”щ_—ˆwx,щ( $ј’rТ-ˆwpёŒwr”ˆwX”ˆwа!8L Œ ьџџџЌщ3)ˆwМщCщ<ъˆј’r)ˆwC>ъ№9р§р§˜ьЇ‹wx”ˆwџџџџЈьЈьТ-ˆwpёŒwV–ˆw.–ˆw№ьъC:\!љ,Љ5˜ `‚Laк– TШpк‚ 3ZШ0Ат DaB…| P!Т—&D8 €€ˆZРxƒO 5 Њц .((€hP @сУM‹О”``‚еiSЖ„šAз LcА…V ЮІeРжm„В)хІ-˜ЁЅП€НЬ@… ˆ#F›0У…Ч#+œЌ0 ;ldap2dns-0.3.1/webadmin/icons/zone_new.gif0100664000100100010010000000166307504105012017373 0ustar jriefjriefGIF89aїџc”џ)c)cџ)”)Ю))Юџ)џc)џџRRRsss„„„”””НННЮџЮЮџџоооччжџїяџџJџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ!љ,-x рЙCD8tk•[.`ИпpуГьCЅVаBьТП@ŠX>@R‰%/0DS  bP1Roj dfp "Ќ­Ќk)ББ!;ldap2dns-0.3.1/webadmin/icons/zone_unre.gif0100664000100100010010000000041307504105012017543 0ustar jriefjriefGIF89aФџџ)cџ”џ)Юџ)џџЮџџ)џcc)Ю)ЮџЮ)”)cччжїЙ4єИ3ћЪaџїяџџџоооННН”””„„„sssRRRРРР!љ,@ˆ &ŠJЉуЈDШ! UЭФL—Ж,ШФ4Ш$RQ•21†r‰#EˆŠtjЩˆТ` R,9EТ€Ptk[.•ЙИпpуГьCЅVаE,ТLŠX>@R‰%/0‘ bP1‘ žj dfžŸM"АБАk)ЕЕ!;ldap2dns-0.3.1/webadmin/icons/zone_val.gif0100664000100100010010000000041007504105012017351 0ustar jriefjriefGIF89aФџџc”џ)c)cџ)”)Ю))Юџ)џc)џџRRRsss„„„”””НННЮџЮЮџџоооччжџїяРРРџџџ!љ,@… %ŠGyуx\ˆ0$ЮUЭеDAŒUHaФД фтP•1Šr‰#]"‡tкˆ ’Eb >ЙCD8tk•[.`ИпpуГьCЅVаBьТП@ŠX>@R‰%/0 ‘d bP1‘jœf,žM"­Ў­k)ВВ!;ldap2dns-0.3.1/webadmin/index.php0100664000100100010010000006554307526217013015605 0ustar jriefjrief0) { zone_edit_plus($zonedn); } else { new_zone($HTTP_GET_VARS[zonename]); } } include("footer.inc"); break; case "editzone": connect_ldap(); include("mainheader.inc"); if (isset($HTTP_POST_VARS[modifysoa])) { modify_zone_soa($HTTP_POST_VARS[zonedn]); log_action("modify_zone_soa: $HTTP_POST_VARS[zonedn]"); } elseif (isset($HTTP_POST_VARS[addrrset])) { add_rrset($HTTP_POST_VARS[zonedn]); log_action("add_rrset: $HTTP_POST_VARS[zonedn]"); } elseif (isset($HTTP_POST_VARS[modifyrrset])) { if (isset($HTTP_POST_VARS[deleterrset])) { delete_rrset($HTTP_POST_VARS[zonedn], $HTTP_POST_VARS[setdn]); log_action("delete_rrset: $HTTP_POST_VARS[setdn]"); } else { modify_rrset($HTTP_POST_VARS[zonedn], $HTTP_POST_VARS[setdn]); log_action("modify_rrset: ".$HTTP_POST_VARS[setdn]); } } if (isset($HTTP_GET_VARS[zonedn])) zone_edit_plus($HTTP_GET_VARS[zonedn]); elseif (isset($HTTP_POST_VARS[zonedn])) edit_zone_attrs($HTTP_POST_VARS[zonedn]); include("footer.inc"); break; case "newzone": connect_ldap(); include("mainheader.inc"); new_zone(); include("footer.inc"); break; case "addzone": connect_ldap(); include("mainheader.inc"); zone_edit_plus(add_zone()); include("footer.inc"); break; case "removezone": connect_ldap(); if (isset($HTTP_GET_VARS[zonedn]) && remove_zone($HTTP_GET_VARS[zonedn])) { include("xearthheader.inc"); include("footer.inc"); } break; } } function full_dns_list() { global $ldap, $BASEDN, $ZONEEDIT, $HTTP_GET_VARS; $letters = array( "0-9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q-R","S","T","U","V","W","X-Z" ); if (isset($HTTP_GET_VARS[wait])) sleep($HTTP_GET_VARS[wait]); if (isset($HTTP_GET_VARS[selet])) $selet = $HTTP_GET_VARS[selet]; ?>
 Find   
" TARGET="main">   Add new Zone
". "". "...$let
\n"; } else { $newselet = $selet.$let; print "". "". "...$let
\n"; continue; } $filter = "(&(objectclass=dnszone)"; if (ereg("([0-9A-Z])-([0-9A-Z])", $let, $regs)) { $filter .= "(|"; for ($i = ord($regs[1]); $i<=ord($regs[2]); $i++) { $filter .= "(cn=".chr($i)."*)"; } $filter .= "))"; } else { $filter .= "(cn=$let*))"; } $query = ldap_search($ldap, $BASEDN, $filter); //ldap_sort($ldap, $query, "cn"); $entries = ldap_get_entries($ldap, $query); ldap_free_result($query); for ($i = 0; $i<$entries[count]; $i++) { $zonedn = $entries[$i]["dn"]; $zonename = $entries[$i]["dnszonename"][0]; $tree2 = ($i==$entries[count]-1 ? "end" : "cont"); print "". "". " $zonename
\n"; } print "\n"; } #print "Without DNS-lookup
\n"; } else { print "With DNS-lookup
\n"; } } function individual_dns_list() { global $ldap, $binddn, $BASEDN, $ZONEEDIT, $HTTP_GET_VARS; $query = ldap_search($ldap, $BASEDN, "(&(objectclass=DNSzone)(owner=$binddn))"); $entries = ldap_get_entries($ldap, $query); for ($i = 0; $i<$entries[count]; $i++) { $zonedn = $entries[$i][dn]; $zonename = $entries[$i][dnszonename][0]; $tree = ($i==$entries[count]-1 ? "end" : "cont"); print "". "". " $zonename
\n"; } } function search_zone($zonename) { global $ldap, $BASEDN; $filter = "(&(objectclass=dnszone)(dnszonename=$zonename))"; $query = ldap_search($ldap, $BASEDN, $filter); $entries = ldap_get_entries($ldap, $query); if ($entries[count]>1) { $mesg = "Ambigous zonenames $zonename in
"; for ($i = 0; $i<$entries[count]; $i++) { $mesg .= "dn: ". $entries[$i]["dn"]."
"; } print "

Warning: $mesg

"; exit; } if ($entries[count]==1) { return $entries[0][dn]; } else switch (authorized($zonename)) { case -2: error_confirm("The zone does not belong to a valid top level domain"); exit; case -1: error_confirm("The zone is owned by someone else"); print_whois($zonename); exit; default: return; } } function print_zone_soa($zonedata, $constr) { print "Serial: "; if (ereg("[amo]", $constr)) { print ""; } else { print " ".$zonedata["dnsserial"]." "; } print "Refresh: "; if (ereg("[amo]", $constr)) { print ""; } else { print " ".$zonedata["dnsrefresh"]." "; } print "\nRetry: "; if (ereg("[amo]", $constr)) { print ""; } else { print " ".$zonedata["dnsretry"]." "; } print "\nExpire: "; if (ereg("[amo]", $constr)) { print ""; } else { print " ".$zonedata["dnsexpire"]." "; } print "\nMinimum: "; if (ereg("[amo]", $constr)) { print ""; } else { print " ".$zonedata["dnsminimum"]." "; } print "\nAdminmailbox: "; if (ereg("[amo]", $constr)) { print ""; } else { print " ".$zonedata["dnsadminmailbox"]." "; } print "\nZonemaster: "; if (ereg("[amo]", $constr)) { print ""; } else { print " ".$zonedata["dnszonemaster"]." "; } print "\nTime to live: "; if (ereg("[amo]", $constr)) { print ""; } else { print " ".$zonedata["dnsttl"]." "; } print "\n"; } function get_zone_name($zonedn) { global $ldap; $query = ldap_read($ldap, $zonedn, "(objectclass=dnszone)", array("dnszonename")); $entries = ldap_get_entries($ldap, $query); $zonename = $entries[0][dnszonename][0]; ldap_free_result($query); return $zonename; } function modify_zone_soa($zonedn) { global $ldap, $ZONE_INFO, $HTTP_POST_VARS; $zonename = get_zone_name($zonedn); $entry = array(); foreach ($ZONE_INFO as $za) { if (strlen($HTTP_POST_VARS["$za"])>0) $entry["$za"] = $HTTP_POST_VARS["$za"]; } if (ereg("[a]", check_constraint($zonedn))) { $entry[dnszonename] = array("$zonename"); for ($i = 0; isset($HTTP_POST_VARS["dnszonename$i"]); $i++) { if (strlen($HTTP_POST_VARS["dnszonename$i"])>3) array_push($entry[dnszonename], $HTTP_POST_VARS["dnszonename$i"]); } } ldap_modify($ldap, $zonedn, $entry) or die("ldap_modify failed to update SOA for $zonedn"); } function authorized($zonename) { return 1; } function zone_edit_plus($zonedn) { $zonename = get_zone_name($zonedn); $auth = authorized($zonename); if ($auth==1) { print "

The nameserver is active and authorized to handle this zone

\n"; edit_zone_attrs($zonedn); print_whois($zonename); } elseif ($auth==0) { print "

The nameserver is not active for this zone

\n"; edit_zone_attrs($zonedn); print_whois($zonename); } elseif ($auth==-1) { print "

The nameserver is not authorized to handle this zone

\n"; edit_zone_attrs($zonedn); print_whois($zonename); } else { print "

Zone $zonename does not not belong to a valid TLD

\n"; delete_zone(); } } function edit_zone_attrs($zonedn) { global $ldap, $ZONE_INFO, $ZONEEDIT, $HTTP_GET_VARS, $HTTP_POST_VARS; if (isset($HTTP_GET_VARS[selet])) $selet = $HTTP_GET_VARS[selet]; elseif (isset($HTTP_POST_VARS[selet])) $selet = $HTTP_POST_VARS[selet]; $query = ldap_read($ldap, $zonedn, "(objectclass=dnszone)"); $entries = ldap_get_entries($ldap, $query); $zonename = $entries[0][dnszonename][0]; ldap_free_result($query); $zonedn = $entries[0][dn]; $zonename0 = $entries[0][dnszonename][0]; $zonenames = array(); for ($i = 1; $i<$entries[0][dnszonename][count]; $i++) { array_push($zonenames, $entries[0][dnszonename][$i]); } $zonedata = array(); foreach ($ZONE_INFO as $za) { $zonedata[$za] = $entries[0][$za][0]; } print "

Edit DNS zone $zonename0

"; $zoneconstr = check_constraint($zonedn); if (ereg("[a]", $zoneconstr)) { # Print modifiable table for SOA if (ereg("[f]", $selet)) { print "
". "". ""; } else { print "". "". "". ""; } print "\n"; $zc = 0; foreach ($zonenames as $zn) { print "\n"; $zc++; } if (ereg("[a]", $zoneconstr)) { print "\n"; } print_zone_soa($zonedata, $zoneconstr); print "
Aliasing Zonename: "; if (ereg("[a]", $zoneconstr)) print ""; else print "$zn"; print "
Add aliasing Zonename: ". "
". "

"; } else { # Print non-modifiable table for SOA print "\n"; foreach ($zonenames as $zn) { print "\n"; } print_zone_soa($zonedata, $zoneconstr); print "
Aliasing Zonename: $zn

\n"; } # Tables for RRsets $query = ldap_list($ldap, $zonedn, "(objectclass=dnsrrset)"); $rrsets = ldap_get_entries($ldap, $query); ldap_free_result($query); print "\n". "". "\n"; for ($i = 0; $i<$rrsets[count]; $i++) { $setdn = $rrsets[$i][dn]; $setconstr = $zoneconstr.check_constraint($setdn); $domainname = $rrsets[$i][dnsdomainname][0]; $ipaddr = $rrsets[$i][dnsipaddr]; $cipaddr = $rrsets[$i][dnscipaddr][0]; $cname = $rrsets[$i][dnscname][0]; $type = $rrsets[$i][dnstype][0]; $ttl = $rrsets[$i][dnsttl][0]; $preference = $rrsets[$i][dnspreference][0]; if (ereg("[amo]", $setconstr)) { if (ereg("[f]", $selet)) { print "". "". "". "". ""; } else { print "". "". "". ""; } } if (ereg("[amo]", $setconstr)) { print "
Delete"; } print ""; if (ereg("[amo]", $setconstr)) { print "\n"; } else { print "\n"; } } if (ereg("[amo]", $setconstr)) { if (ereg("[f]", $selet)) { print "\n". "". "". "". "". "". "". "". ""; } print "
DNS NameTypeMappingTTL/Pref 
$type"; if ($type=="CNAME" || $type=="MX" || $type=="NS") { print ""; if (ereg("[amo]", $setconstr)) print "\n"; else print "\n"; } if ($type=="A" || $type=="MX" || $type=="NS") { if (ereg("[a]", $setconstr)) { print "". "\n"; } else if (isset($cipaddr)) { print "\n"; } for ($k = 0; $k<$rrsets[$i][dnsipaddr][count]; $k++) { print ""; $ipaddr = $rrsets[$i][dnsipaddr][$k]; if (ereg("[amo]", $setconstr)) print "\n"; else print "\n"; } if (ereg("[amo]", $setconstr)) { print "\n"; } } print "
CName:
$cname
Canonical IP:
Canonical IP:$cipaddr
Modify IP:
$ipaddr
Add IP:
TTL: "; if ($type=="MX") print "
Pref: "; print "
TTL: $ttl"; if ($type=="MX") print "
Pref: $preference"; print "
 

\n"; print ""; // 'Delete' form $onclick = "if(confirm('Do you really want to remove zone: $zonename0 and all its resource records?'))"; if (ereg("[f]", $selet)) { $onclick .= "{ parent.frames.menu.location='$ZONEEDIT?call=dnslist&selet=$selet&wait=1';". "parent.frames.main.location='$ZONEEDIT?call=removezone&zonedn=$zonedn&selet=$selet'; }"; } else { $onclick .= "{ parent.window.location='$ZONEEDIT?call=removezone&zonedn=$zonedn'; }"; } if (ereg("[am]", $setconstr)) { print "\n"; } // form for reset/refresh button if (ereg("[f]", $selet)) { print "". "". "". ""; } else { print "". "". ""; } print "". "
\n"; } function new_zone($new_zonename = "") { global $HTTP_GET_VARS, $ZONE_SOA, $ZONEEDIT, $BASEDN; if (isset($HTTP_GET_VARS[selet])) $selet = $HTTP_GET_VARS[selet]; $zonedata = $ZONE_SOA; $zonedata[dnsserial] = new_serial(); $onsubmit = "{ parent.frames.menu.location='$ZONEEDIT?call=dnslist&selet=$selet&wait=1'; }"; print "

Add new DNS zone

"; print "
". "". "". "\n". "\n"; print_zone_soa($zonedata, check_constraint()); print "
New Zonename: ". "". "
". "". "". "". "
\n". "
"; } function add_zone() { global $ldap, $HTTP_POST_VARS, $BASEDN, $ZONE_SOA, $ZONE_ENTRY, $ZONE_INFO; $zonedata = array(); foreach ($ZONE_INFO as $za) { if (strlen($HTTP_POST_VARS[$za])>0) { $zonedata[$za] = $HTTP_POST_VARS[$za]; } } $zonedata["cn"] = $zonedata["dnszonename"]; $zonedata["objectclass"] = "dnszone"; $zonedn = "cn=$zonedata[cn],$BASEDN"; ldap_add($ldap, $zonedn, $zonedata) or die("Failed to add zonedn: $zonedn"); foreach ($ZONE_ENTRY as $ze) { $dnch = "cn=$ze[cn],$zonedn"; ldap_add($ldap, $dnch, $ze) or die("Failed to add rrset dn: $dnch"); } return $zonedn; } function remove_zone($zonedn) { global $ldap; $query = ldap_list($ldap, $zonedn, "(objectclass=DNSrrset)"); $entries = ldap_get_entries($ldap, $query); ldap_free_result($query); for ($i = 0; $i<$entries[count]; $i++) { ldap_delete($ldap, $entries[$i][dn]) or die("Failed to delete dn: $entries[$i][dn]"); } ldap_delete($ldap, $zonedn) or die("Failed to delete dn: $zonedn"); return 1; } function new_serial($zonedn = 0) { global $ldap; $newserial = date("Ymd")."00"; if ($zonedn) { $query = ldap_read($ldap, $zonedn, "(objectclass=DNSzone)"); $entries = ldap_get_entries($ldap, $query); $oldserial = $entries[0][dnsserial][0]; } return ($newserial>$oldserial) ? $newserial : $oldserial+1; } function add_rrset($zonedn) { global $ldap, $binddn, $HTTP_POST_VARS, $DEFAULT_TTL, $DEFAULT_PREFERENCE; if (!isset($HTTP_POST_VARS[dnsdomainname])) die("No domainname specified"); if (strlen($HTTP_POST_VARS[dnsdomainname])>0) $entry[dnsdomainname] = $HTTP_POST_VARS[dnsdomainname]; if (!isset($HTTP_POST_VARS[dnstype])) die("No type specified"); $entry[dnstype] = $HTTP_POST_VARS[dnstype]; $entry[dnsclass] = "IN"; // INternet is hardcoded $entry[dnsttl] = $DEFAULT_TTL; // $entry[owner] = $binddn; if ($entry[dnstype]=="MX" || $entry[dnstype]=="NS") { for ($i = 1;; $i++) { $setcn = "$entry[dnstype]$i:$entry[dnsdomainname]"; $query = ldap_list($ldap, $zonedn, "(&(objectclass=dnsrrset)(cn=$setcn))"); $rrset = ldap_get_entries($ldap, $query); ldap_free_result($query); if ($rrset[count]==0) break; } if ($entry[dnstype]=="MX") $entry[dnspreference] = $DEFAULT_PREFERENCE; } else { $setcn = "$entry[dnstype]:$entry[dnsdomainname]"; $query = ldap_list($ldap, $zonedn, "(&(objectclass=dnsrrset)(cn=$setcn))"); $rrset = ldap_get_entries($ldap, $query); ldap_free_result($query); if ($rrset[count]>0) { error_confirm("$entry[dnsdomainname] has already been added to this zone"); return; } } $entry[objectclass] = "dnsrrset"; $entry[cn] = $setcn; $setdn = "cn=$setcn,$zonedn"; ldap_add($ldap, $setdn, $entry) or die("Faild to add DNSrrset $setdn to DNSzone $zonedn"); } function modify_rrset($zonedn, $setdn) { global $ldap, $HTTP_POST_VARS; $zonename = get_zone_name($zonedn); $entry = array(); if (isset($HTTP_POST_VARS[dnscname])) { if ($HTTP_POST_VARS[dnscname]=="") { $entry[dnscname] = array(); } elseif (ereg("\.$", $HTTP_POST_VARS[dnscname])) { if (checkdnsrr($HTTP_POST_VARS[dnscname], "A")) { $entry[dnscname] = $HTTP_POST_VARS[dnscname]; } else { error_confirm("Error: $HTTP_POST_VARS[dnscname] does not resolve to a valid IP-address"); return; } } elseif (isset($HTTP_POST_VARS[dnsipaddr0]) || isset($HTTP_POST_VARS[dnscipaddr])) { // records with their own address settings are not checked against DNS $entry[dnscname] = $HTTP_POST_VARS[dnscname]; } else { if (!checkdnsrr("$HTTP_POST_VARS[dnscname].$zonename", "A")) { print "

Warning: $HTTP_POST_VARS[dnscname].$zonename". " does not resolve to a valid IP-address

\n"; } $entry[dnscname] = $HTTP_POST_VARS[dnscname]; } } if (isset($HTTP_POST_VARS[dnscipaddr])) { if (ereg("^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$", $HTTP_POST_VARS[dnscipaddr], $reg)) { $regip = "$reg[1].$reg[2].$reg[3].$reg[4]"; if (check_unique_cipaddr($setdn, $regip)) $entry[dnscipaddr] = $regip; else return; } elseif ($HTTP_POST_VARS[dnscipaddr]=="") { $entry[dnscipaddr] = array(); } else { error_confirm("$HTTP_POST_VARS[dnscipaddr] is not a valid IP-address"); return; } } if (isset($HTTP_POST_VARS[dnsttl])) { if (ereg("([0-9]+)", $HTTP_POST_VARS[dnsttl], $reg)) { $entry[dnsttl] = $reg[1]; } else { error_confirm("$HTTP_POST_VARS[dnsttl] is not a valid Time To Live"); return; } } if (isset($HTTP_POST_VARS[dnspreference])) { if (ereg("([0-9]+)", $HTTP_POST_VARS[dnspreference], $reg)) { $entry[dnspreference] = $reg[1]; } else { error_confirm("$HTTP_POST_VARS[dnspreference] is not a valid MX-prefrence"); return; } } $entry[dnsipaddr] = array(); for ($i = 0; isset($HTTP_POST_VARS["dnsipaddr$i"]); $i++) { $ipaddr = $HTTP_POST_VARS["dnsipaddr$i"]; if (ereg("^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$", $ipaddr, $reg)) { array_push($entry[dnsipaddr], "$reg[1].$reg[2].$reg[3].$reg[4]"); } elseif ($ipaddr!="") { error_confirm("$ipaddr is not a valid IP-address"); return; } } ldap_modify($ldap, $setdn, $entry) or die("Faild to modify DNSrrest $setdn in DNSzone $zonedn"); ldap_mod_replace($ldap, $zonedn, array("dnsserial"=>new_serial($zonedn))); } function delete_rrset($zonedn, $setdn) { global $ldap; ldap_delete($ldap, $setdn) or die("Failed to delete $setdn from LDAP");; ldap_mod_replace($ldap, $zonedn, array("dnsserial"=>new_serial($zonedn))); } function check_unique_cipaddr($setdn, $cipaddr) { global $ldap, $BASEDN; $query = ldap_search($ldap, $BASEDN, "(&(objectclass=dnsrrset)(dnscipaddr=$cipaddr))"); $entries = ldap_get_entries($ldap, $query); ldap_free_result($query); for ($i = 0; $i<$entries[count]; $i++) { $dn = $entries[$i][dn]; if ($dn!=$setdn) { error_confirm("Canonical IP-address $cipaddr is already used by $dn"); return 0; } } return 1; } function print_whois($zonename) { global $WHOISSERVERS; return; // weil unser FW-Gschaftler den Port 43 von innen nach aussen zugedreht hat if (ereg("\.([a-zA-Z]+)$", $zonename, $regex)) { $whoissrv = $WHOISSERVERS["$regex[1]"]; if (isset($whoissrv)) { $whoisrecord = system("whois -h $whoissrv $zonename"); print "

Whois-record for zone $zonename

\n". "as serverd by $whoissrv
\n". "". "
$whoisrecord
\n"; } else { print "

No WHOIS-Server found for \"$regex[1]\"

\n"; } } } ?> ldap2dns-0.3.1/webadmin/main.css0100664000100100010010000000036507504127117015413 0ustar jriefjriefBODY, TD { font-family: Verdana,Arial,Helvetica; font-size: 11pt; background-color: white; color: black; } SMALL { font-family: Verdana,Arial,Helvetica; font-size: 8pt; } BIG { font-family: Verdana,Arial,Helvetica; font-size: 14pt; } ldap2dns-0.3.1/webadmin/mainheader.inc0100664000100100010010000000022607504127117016541 0ustar jriefjrief Zone-Editor ldap2dns-0.3.1/webadmin/menu.css0100664000100100010010000000101707504127117015426 0ustar jriefjriefA { text-decoration: none; } A:link { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; color: black; } A:visited { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 10px; color: #222222; } A:hover { text-decoration: underline; } BODY, TD { font-family: Verdana,Arial,Helvetica; font-size: 10pt; background-color: lightgrey; color: black; } SMALL { font-family: Verdana,Arial,Helvetica; font-size: 8pt; } BIG { font-family: Verdana,Arial,Helvetica; font-size: 14pt; } ldap2dns-0.3.1/webadmin/menuheader.inc0100664000100100010010000000031407504317367016567 0ustar jriefjrief Zone-Selector
ldap2dns-0.3.1/webadmin/.htaccess0100644000100100010010000000004607526200327015544 0ustar jriefjriefAddType application/x-httpd-php .php ldap2dns-0.3.1/webadmin/common.inc0100664000100100010010000000431607526216675015754 0ustar jriefjrief

$errmsg


\n"; log_action("error: ".$errmsg); } function log_action($errmsg) { global $LOGFILE, $REMOTE_ADDR, $PHP_AUTH_USER; $fd = fopen("$LOGFILE", "a"); fwrite($fd, "[".date("H:i:s d/M/Y")."] $PHP_AUTH_USER@$REMOTE_ADDR $errmsg\n"); fclose($fd); } # Use this function to determine contraints on objects and returns a set # of characters with the following meaning: # o: binddn owns the object # a: binddn is administrator # m: binddn is member function check_constraint($dn = "") { global $ldap, $binddn, $BASEDN; $result = ""; $num_owners = 0; if (strlen($dn)>0) { // get owners for this object $query = ldap_read($ldap, $dn, "(objectclass=*)", array("owner")); $entries = ldap_get_entries($ldap, $query); ldap_free_result($query); $num_owners = $entries[0][owner][count]; for ($i = 0; $i<$num_owners; $i++) { if ($entries[0][owner][$i]==$binddn) { $result .= "o"; $num_owners = 0; } } } // get administrators for BASEDN $query = ldap_read($ldap, $BASEDN, "(objectclass=*)", array("administrator", "member")); $entries = ldap_get_entries($ldap, $query); ldap_free_result($query); for ($i = 0; $i<$entries[0][administrator][count]; $i++) { if ($entries[0][administrator][$i]==$binddn) { $result .= "a"; break; } } if ($num_owners==0) { // only objects owned by nobody except binddn are granted to members for ($i = 0; $i<$entries[0][member][count]; $i++) { if ($entries[0][member][$i]==$binddn) { $result .= "m"; break; } } } print ""; return $result; } ?> ldap2dns-0.3.1/webadmin/xearth.css0100664000100100010010000000042407526202375015762 0ustar jriefjriefA { text-decoration: none; } BODY, TD { font-family: Verdana,Arial,Helvetica; font-size: 10pt; background-color: black; color: white; } SMALL { font-family: Verdana,Arial,Helvetica; font-size: 8pt; } BIG { font-family: Verdana,Arial,Helvetica; font-size: 12pt; } ldap2dns-0.3.1/webadmin/xearthimage.php0100664000100100010010000000014607526202375016765 0ustar jriefjrief ldap2dns-0.3.1/webadmin/xearth.php0100664000100100010010000000101307526202470015750 0ustar jriefjrief XEarth




ldap2dns-0.3.1/Makefile0100660000100100010010000000252207526217223013622 0ustar jriefjrief# $Id: Makefile,v 1.29 2002/08/02 15:19:36 jrief Exp $ VERSION=0.3.1 RELEASE=1 CC=gcc -O2 CCDEBUG=gcc -g CFLAGS=$(INC) -DVERSION='"$(VERSION)"' LIBS=-lldap -llber LD=gcc LDFLAGS= INSTALL_PREFIX= PREFIXDIR=$(INSTALL_PREFIX)/usr LDAPCONFDIR=$(INSTALL_PREFIX)/etc/openldap TARFILE=/usr/src/redhat/SOURCES/ldap2dns-$(VERSION).tar.gz SPECFILE=ldap2dns.spec all: ldap2dns ldap2dnsd ldap2dns-dbg ldap2dns: ldap2dns.o $(LIBS) $(LD) $(LDFLAGS) -o $@ $+ ldap2dnsd: ldap2dns ln -f ldap2dns ldap2dnsd ldap2dns-dbg: ldap2dns.o-dbg $(LIBS) $(LD) $(LDFLAGS) -o $@ $+ ldap2dns.o: ldap2dns.c $(CC) $(CFLAGS) -c $< -o $@ ldap2dns.o-dbg: ldap2dns.c $(CCDEBUG) $(CFLAGS) -c $< -o $@ install: all mkdir -p $(PREFIXDIR)/bin mkdir -p $(LDAPCONFDIR) install -s -o root -g root -m 755 ldap2dns $(PREFIXDIR)/bin/ ln -f $(PREFIXDIR)/bin/ldap2dns $(PREFIXDIR)/bin/ldap2dnsd install -o root -g root -m 755 ldap2tinydns-conf $(PREFIXDIR)/bin/ install -o root -g root -m 644 dns.at.conf $(LDAPCONFDIR)/ install -o root -g root -m 644 dns.oc.conf $(LDAPCONFDIR)/ clean: rm -f *.o *.o-dbg ldap2dns ldap2dnsd data* *.db core $(SPECFILE) tar: clean cd ..; \ tar czf $(TARFILE) ldap2dns-$(VERSION) --exclude CVS $(SPECFILE): Specfile sed -e 's#%VERSION%#$(VERSION)#g' \ -e 's#%RELEASE%#$(RELEASE)#g' \ < $< > $@ rpm: tar $(SPECFILE) rpm -ba $(SPECFILE) ldap2dns-0.3.1/README.html0100664000100100010010000004144607257624037014027 0ustar jriefjrief

LDAP to DNS gateway

ldap2dns is a program to create DNS (Domain Name Service) records directly from a LDAP directory. It can and should be be used to replace the secondary name-server by a second primary one.
ldap2dns reduces all kind of administration overhead: No more flat file editing, no more zone file editing. After having installed ldap2dns, the administrator only has to access the LDAP directory.
Optionally she can add access control for each zone, create a GUI and add all other kind of zone and resource record information without interfering with the DNS server.
ldap2dns is designed to write ASCII data files used by tinydns from the djbdns package, but also may be used to write .db-files used by named as found in the BIND package.

1. Introduction

Often it is desirable to store DNS information in a database rather than in flat text files. This can greatly help to reduce administration overhead since associate information such as billing contact, account management, etc. can be stored and processed inside the same database. Also due to the nature of DNS, information must be stored redundantly on two or more hosts. The classical data replication through zone transfer is unreliable, insecure and difficult to administer.
To solve this problem some proprietary attempts have been proposed to store DNS information in relational databases. The nature of DNS, however, is hierarchical and such should the database be. Using a relational database to store DNS information is undesirable, because it becomes difficult to store free form information. Within a hierachical data scheme, the administrator might define more than one IP-address for each canonical name. To implement such a feature in a relational database without breaking the normalization rules, one would have to add another table.
One of the most widely spread hierarchical database protocols is LDAP. ldap2dns retrieves DNS information stored in an LDAP directory service and generates a file suitable for name-servers.
Actually the most widely spread name-servers named and tinydns are supported. ldap2dns specially has been designed to work with tinydns and is the favored name server daemon for the author of this program. ldap2dns can also generate files suitable for named version 8, but this feature is not well supported. There is a RFC for a format description how to store DNS information in LDAP. This paper a draft RFC which expired in February 1999, looks as if it has been specially designed to be used by named. This scheme does not have strict attribute-value-pair mapping, making it difficult to be used by user interfaces. It also lacks of an implementation (or I have never heard of any).
Since tinydns is going another descriptive way. Therefore I implemented a similar object-scheme more suitable for tinydns. Two object-classes have been defined. DNSzone stores all the information to define a DNS zone, such as the SOA (Start Of Authority), serial numbers etc. DNSrrset is used to store the information for a single resource record, such as the domain name, IP-addresses, class and type.
Here are the tables:

DNSzone

This object-class represents a DNS zone. It is the container for all the resource records within a zone. Zones can be primary or secondary. If used in conjunction with tinydns zones are always primary. Secondary zones don't make sense anyway! In addition to being a container, the zone object has attributes related to the management of the zone. These include the zone's SOA information. Each zone-object can have none to many children of class DNSrrset.
ATTRIBUTEVALUEComment
objectclassDNSzonerequired
cncommon namerequired
DNSzonenameName of the zonerequired, multivalued
DNSserialSerial number of SOAoptional
DNSrefreshRefresh time of SOAoptional, only used for zone transfers
DNSretryRetry time of SOAoptional, only used for zone transfers
DNSexpireExpire time of SOAoptional, only used for zone transfers
DNSminimumMinimum time to liveoptional, only used for zone transfers
DNSadminmailboxHostmaster's contact addressoptional
DNSzonemasterPrimary nameserver for this zoneoptional
DNStypeSOAmust be SOA
DNSclassINmust be IN
DNSttltime to liveoptional, only used with tinydns
DNStimestamptimestampoptional, only used with tinydns
  • DNSzonename: This field is required to describe the zone's domain name, for instance myorg.com. More than one DNSzonename my be specified for a DNSzone so that the same host is accessable with different zonenames.
  • DNSserial: This is the serial number as used for BIND's zone transfers. Here it is used to inform ldap2dns that it has to rebuild its data-file. Without increasing the serial number ldap2dns will ignore all modifications until it is restarted.
  • DNSrefresh, DNSretry, DNSexpire, DNSminimum: You may safly ignore these numbers if You don't do zone-transfers. Since Your secondary nameserver will connect to the LDAP server the same way Your primary does, You don't need zone-transfers anyway.
  • DNSzonemaster: Here you specify the canonical name of your primary nameserver.
  • DNSadminmailbox: This is the contact address of Your DNS-administrator. The first dot is converted to a @.
  • DNStype: Must be SOA (Start Of Authority)
  • DNSclass: Must be IN (Internet, or do still use Chaosnet?)
  • DNSttl: This is the time-to-live value as used by tinydns. If TTL is nonzero (or omitted), the timestamp is a starting time from whereon this zone's information is valid. If TTL is zero, the timestamp is an ending time (``time to die'').
  • DNStimestamp: This is the timestamp as used by tinydns. It represents a string as external TAI64 timestamp, printed as 16 lowercase hexadecimal characters

DNSrrset

The Resource Record Set represents all of the resource records for a given host name within a zone. It must be a child of a DNSzone object.
ATTRIBUTEVALUEComment
objectclassDNSrrsetrequired
cncommon namerequired
DNSdomainnameName of this recordoptional, relative to zonename
DNSipaddrIP addressoptional, mutivalued
DNScnameCanonical nameoptional, without ending dot relative to zonename
DNSpreferenceintegeroptional, only used for MX records
DNStypeA, CNAME, NS, MX, PTR or TXTmust be any valid record type
DNSclassINmust be IN
DNSttltime to liveoptional, only used with tinydns
DNStimestamptimestampoptional, only used with tinydns

  • DNSrrset: This object-class must be a direct child of DNSzone. Its dn should be specified as
    cn=domainname,cn=zonename,...
  • DNSdomainname This is the partial domain-name, ie. the part in front of the zone-name.
  • DNSipaddr: This specifies the IP-address in dotted format. It can be used for DNSrrset's of type A, NS, MX or PTR. DNSipaddr is multivalued to specifiy more than one IP-address for a service. If used in DNSrrset's with DNStype = PTR it overrides the old-fashioned form used in DNSdomainname such as 13.178.23.in-addr.arpa for reverse lookups.
  • DNScname: Whenever there is a mapping of a domain-name to a canonical name, use this attribute. DNScname may be used for DNSrrset's with DNStype CNAME, NS, MX, PTR or TXT. If the last character of a CNAME is a dot its name is considered absolute. If it does not contain a dot, its name is prepended to the zone-name.
  • DNSpreference: This number is the mail-exchange preference as used by BIND.
  • DNStype: This must be A, CNAME, NS, MX, PTR or TXT. It specifies the DNSrrset type.
  • DNSclass: Must be IN
  • DNSttl: This is the time-to-live value as used by tinydns. If TTL is non-zero (or omitted), the time-stamp is a starting time from where-on this zone's information is valid. If TTL is zero, the timestamp is an ending time (``time to die'').
  • DNStimestamp: This is the timestamp as used by tinydns. It represents a string as external TAI64 time-stamp, printed as 16 lowercase hexadecimal characters

2. Installation

  • Install an LDAP server such as openldap. Other LDAP implementations may work but have not been tested. Also install the development libraries and include files.
  • Install djbdns or if you really have to, go with BIND.
    I suggest to install tinydns included in the djbdns package, because it is safer, but You may have reasons why You want to use BIND.
  • Install ldap2dns
    Unpack the package and build it:
    gzcat ldap2dns.tar.gz | tar x
    cd ldap2dns-version
    make
    make install
    
    If you run ldap2dns togther with tinydns, go into /var/tinydns and run ldap2tinydns-conf.
  • Add the extra object-classes to the slapd.conf file. If You are using openldap-1.2.x:
    copy the files dns.oc.conf and dns.ac.conf into the directory /etc/openldap or appropriate and add the following two lines to Your slapd.conf file:
    include         /etc/openldap/dns.at.conf
    include         /etc/openldap/dns.oc.conf
    
    or, if You are using openldap-2.0.x:
    copy the file dns.schema into the directory /etc/openldap/schema or appropriate and add the following line to Your slapd.conf file:
    include         /etc/openldap/schema/dns.schema
    
    Now restart your LDAP server.
  • Start to populate your LDAP server with DNS information. As a first test do
    $ ldapadd -D "binddn" -w password < example.ldif
    
    Replace 'myorg' and 'binddn' with whatever is appropriate on Your system. Start a search and see if something was added
    $ ldapsearch -D "binddn" "objectclass=dnsrrset" 
  • Test ldap2dns
    $ ./ldap2dns -D "binddn" [ -b "searchbase" ] [ -w passwd ] -o data -o db -L
    
    This should create a 'data' file, a 'corp.local.db' file and should print the DNS content.
    Note: The data file is text data which can be processed with tinydns-data. corp.local.db is the file as used by named. If You are using bind, You also have to adopt the file /etc/named.conf and You have to restart named.

3. Running ldap2dns

If You are a tinydns user, run ldap2dns in /services/tinydns/root.
If You are an openldap user, the command line switches are the same as for ldapsearch or ldapadd.
$ ldap2dns -D "binddn" [ -w passwd ] -b "searchbase" -o data -e "cd /var/tinydns/root && /usr/bin/tinydns-data"
This generates a data file which is converted into a data.cdb by tinydns-data as soon as ldap2dns detects a modification in the LDAP directory. The password is required if You restrict read queries to authenticated users only. Test with
$ dnsq any corp.local ipaddr
Replace ipaddr with whatever You configured tinydns to listen to.

If You are a BIND user, run ldap2dns in /var/named with

$ ldap2dns -D "binddn" -w passwd -b "searchbase" -o db -e "kill -HUP `cat /var/run/named-pid`"
Do not forget to add You primary definition to Your named.boot file. Your named should be restarted automatically as soon as ldap2dns detects a modification in the LDAP directory. If bind is not restarted, do so with
# kill -HUP PID
Now run
$ nslookup - localhost
> ns1.corp.local
Note that nslookup only works with tinydns if Your nameserver resolves its IP-address backwards.

4. Running ldap2dnsd

ldap2dnsd is a hard link onto ldap2dns. If invoked, the program starts as backgound-daemon and contineously checks for modifications in the LDAP directory. If the the daemon sees a modification in the DNSserial numbers it updates the data or .db files, depending what kind of output was configured. This check is done about once a minute.
The command-line options for ldap2dnsd are the same as for ldap2dns. Use the -u option to modify the update intervall. You may also use -u on ldap2dns to start as a foreground daemon. This is useful if You want to run ldap2dns from daemontools. To do this run ldap2tinydns-conf in /service/tinydns and link /service/ldap2dns onto /service/tinydns/ldap2dns.
# ln -s /service/tinydns/ldap2dns /service/ldap2dns
After a few seconds daemontools starts ldap2dns which itself generates data files whenever a modification is commited into the LDAP directory.

ldap2dns and ldap2dnsd recognize the following options:

-D binddn specify the distinguished name to bind to the LDAP directory
-w bindpasswd use bindpasswd as the password for simple authentication
-b searchbase use searchbase as the starting point for the search instead of the default
-o Generate a "data" file to be processed by tinydns-data. 
-o db	For each zone generate a ".db" file to be used by named.
-L[filename] print output in LDIF format for reimport. If no filename is specified output goes to stdout. 
-h host specify the hostname of LDAP directory. Default is localhost.
-p port portnumber to connect to LDAP directory. Defaults is 389
-v run in verbose mode
-vv even more verbose
-V print version and exit
-u numsecs update DNS data every numsecs.
ldap2dns and ldap2dnsd recognizes the following environement variables:
TINYDNSDIR: Specifies the directory where ldap2dns writes its data file.
LDAP2DNS_UPDATE: Specifies the update intervall as the -u command line option would.
LDAP2DNS_OUTPUT: Specifies the default output, as the -o command line option would.

ldap2dns and ldap2dnsd use the following parameters from /etc/ldap.conf if not specified on the command line: BASE: The LDAP search base.
HOST: The LDAP server.
PORT: The LDAP port.

5. Importing DNS data from Your named

A perl-script import.pl is contained in this package. Edit the first lines of the script to conform to Your configuration. If You have installed the Perl packages Net::LDAP and Net::DNS skip the following lines, otherwise do
# perl -MCPAN -e 'shell'
(...snip...)
> install Net::DNS
> install Net::LDAP
Now check that Your nameserver allows zone transfers to your host and run the import script:
$ echo 'primary mydomain.org ' | ./import.pl
for a single domain or
# cat named.boot | ./import.pl
to populate Your LDAP directory.

6. Coming soon

A browser-based administration toolkit, which connects directly to the LDAP-directory service. Here is a screenshot

7. To Do

  • Write a man page.
  • named.conf should be created automatically.

8. Copyright and disclaimer

This program is licensed under the GPL version 2 or at Your choice any later version.
It is maintained by Jacob Rief. If you run ldap2dns on a productive nameserver, please mail me and tell me on what OS and with which nameserver you do so. ldap2dns-0.3.1/Specfile0100664000100100010010000000271707257624037013657 0ustar jriefjrief%define djbdns djbdns-1.02 Summary: LDAP to DNS gateway. Name: ldap2dns Version: %VERSION% Release: %RELEASE% Copyright: GPL Group: Daemons/DNS Source: ldap2dns-%{version}.tar.gz BuildRoot: /var/tmp/%{name}-root Requires: openldap %description ldap2dns is a program to create DNS records directly from an LDAP database. It can be be used to replace the secondary name-server by a second primary one. ldap2dns helps to reduce all kind of administration overhead. No more flat file editing, no more zone file editing. After having installed ldap2dns, the administrator only has to access the LDAP database. If he desires he can add access control for each zone, create a webbased GUI and add all other kind of zone and resource record information without interfering with the DNS server. ldap2dns is designed to write binary data.cdb files used by tinydns, but also may be used to write .db-files used by named. %prep %setup %build make VERSION=%{version} RPM_OPT_FLAGS="$RPM_OPT_FLAGS" %install [ -n "%{buildroot}" -a "%{buildroot}" != / ] && rm -rf %{buildroot} make INSTALL_PREFIX=$RPM_BUILD_ROOT install %clean [ -n "%{buildroot}" -a "%{buildroot}" != / ] && rm -rf %{buildroot} %files %defattr(-,root,root) /usr/bin/ldap2dns /usr/bin/ldap2dnsd /usr/bin/ldap2tinydns-conf %doc README.html %doc import.pl %config /etc/openldap/dns.at.conf %config /etc/openldap/dns.oc.conf %changelog * Wed Dec 06 2000 Jacob Rief - initial revision for version 0.2.0 ldap2dns-0.3.1/djbdns-1.0.5.patch0100644000000000000000000007500507526176353014672 0ustar rootrootdiff -Naur djbdns-1.05.orig/Makefile djbdns-1.05/Makefile --- djbdns-1.05.orig/Makefile Sun Feb 11 22:11:45 2001 +++ djbdns-1.05/Makefile Tue Aug 13 14:28:52 2002 @@ -1,9 +1,6 @@ -# Don't edit Makefile! Use conf-* for configuration. - -SHELL=/bin/sh - default: it + alloc.a: \ makelib alloc.o alloc_re.o getln.o getln2.o stralloc_cat.o \ stralloc_catb.o stralloc_cats.o stralloc_copy.o stralloc_eady.o \ @@ -55,8 +52,8 @@ prot.o timeoutread.o timeoutwrite.o dns.a libtai.a alloc.a env.a \ cdb.a buffer.a unix.a byte.a ./load axfrdns iopause.o droproot.o tdlookup.o response.o \ - qlog.o prot.o timeoutread.o timeoutwrite.o dns.a libtai.a \ - alloc.a env.a cdb.a buffer.a unix.a byte.a + qlog.o prot.o timeoutread.o timeoutwrite.o askldap.o dns.a libtai.a \ + alloc.a env.a cdb.a buffer.a unix.a byte.a `cat ldap.lib` axfrdns-conf: \ load axfrdns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a @@ -626,11 +623,11 @@ ./compile parsetype.c pickdns: \ -load pickdns.o server.o response.o droproot.o qlog.o prot.o dns.a \ +load pickdns.o server.o response.o droproot.o qlog.o prot.o askldap.o dns.a \ env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib ./load pickdns server.o response.o droproot.o qlog.o \ - prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ - byte.a `cat socket.lib` + prot.o askldap.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ + byte.a `cat socket.lib` `cat ldap.lib` pickdns-conf: \ load pickdns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a @@ -704,11 +701,11 @@ ./compile random-ip.c rbldns: \ -load rbldns.o server.o response.o dd.o droproot.o qlog.o prot.o dns.a \ +load rbldns.o server.o response.o dd.o droproot.o qlog.o prot.o askldap.o dns.a \ env.a libtai.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib ./load rbldns server.o response.o dd.o droproot.o qlog.o \ - prot.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ - byte.a `cat socket.lib` + prot.o askldap.o dns.a env.a libtai.a cdb.a alloc.a buffer.a unix.a \ + byte.a `cat socket.lib` `cat ldap.lib` rbldns-conf: \ load rbldns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a @@ -792,6 +789,9 @@ && echo -lsocket -lnsl || exit 0 ) > socket.lib rm -f trylsock.o trylsock +ldap.lib: + echo -lldap -llber > ldap.lib + socket_accept.o: \ compile socket_accept.c byte.h socket.h uint16.h ./compile socket_accept.c @@ -978,13 +978,17 @@ timeoutwrite.h ./compile timeoutwrite.c +askldap.o: \ +compile askldap.c askldap.h + ./compile askldap.c + tinydns: \ load tinydns.o server.o droproot.o tdlookup.o response.o qlog.o \ -prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a byte.a \ -socket.lib +prot.o askldap.o dns.a libtai.a env.a cdb.a alloc.a buffer.a unix.a byte.a \ +socket.lib ldap.lib ./load tinydns server.o droproot.o tdlookup.o response.o \ - qlog.o prot.o dns.a libtai.a env.a cdb.a alloc.a buffer.a \ - unix.a byte.a `cat socket.lib` + qlog.o prot.o askldap.o dns.a libtai.a env.a cdb.a alloc.a buffer.a \ + unix.a byte.a `cat socket.lib` `cat ldap.lib` tinydns-conf: \ load tinydns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a @@ -1015,26 +1019,26 @@ tinydns-edit.o: \ compile tinydns-edit.c stralloc.h gen_alloc.h buffer.h exit.h open.h \ getln.h buffer.h stralloc.h strerr.h scan.h byte.h str.h fmt.h ip4.h \ -dns.h stralloc.h iopause.h taia.h tai.h uint64.h taia.h +dns.h stralloc.h iopause.h taia.h tai.h uint64.h taia.h askldap.h ./compile tinydns-edit.c tinydns-get: \ load tinydns-get.o tdlookup.o response.o printpacket.o printrecord.o \ parsetype.o dns.a libtai.a cdb.a buffer.a alloc.a unix.a byte.a ./load tinydns-get tdlookup.o response.o printpacket.o \ - printrecord.o parsetype.o dns.a libtai.a cdb.a buffer.a \ - alloc.a unix.a byte.a + printrecord.o parsetype.o askldap.o dns.a libtai.a cdb.a buffer.a \ + alloc.a unix.a byte.a `cat ldap.lib` tinydns-get.o: \ compile tinydns-get.c str.h byte.h scan.h exit.h stralloc.h \ gen_alloc.h buffer.h strerr.h uint16.h response.h uint32.h case.h \ printpacket.h stralloc.h parsetype.h ip4.h dns.h stralloc.h iopause.h \ -taia.h tai.h uint64.h taia.h +taia.h tai.h uint64.h taia.h askldap.h ./compile tinydns-get.c tinydns.o: \ compile tinydns.c dns.h stralloc.h gen_alloc.h iopause.h taia.h tai.h \ -uint64.h taia.h +uint64.h taia.h askldap.h ./compile tinydns.c uint16_pack.o: \ @@ -1084,11 +1088,11 @@ ./compile utime.c walldns: \ -load walldns.o server.o response.o droproot.o qlog.o prot.o dd.o \ +load walldns.o server.o response.o droproot.o qlog.o prot.o dd.o askldap.o \ dns.a env.a cdb.a alloc.a buffer.a unix.a byte.a socket.lib ./load walldns server.o response.o droproot.o qlog.o \ - prot.o dd.o dns.a env.a cdb.a alloc.a buffer.a unix.a \ - byte.a `cat socket.lib` + prot.o dd.o askldap.o dns.a env.a cdb.a alloc.a buffer.a unix.a \ + byte.a `cat socket.lib` `cat ldap.lib` walldns-conf: \ load walldns-conf.o generic-conf.o auto_home.o buffer.a unix.a byte.a diff -Naur djbdns-1.05.orig/askldap.c djbdns-1.05/askldap.c --- djbdns-1.05.orig/askldap.c Thu Jan 1 01:00:00 1970 +++ djbdns-1.05/askldap.c Tue Aug 13 14:30:18 2002 @@ -0,0 +1,750 @@ +/* Patch for tinydns to pass DNS-query to LDAP in favour of a cdb lookup. + * $Id$ + * Copyright 2002 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "alloc.h" +#include "byte.h" +#include "response.h" +#include "askldap.h" +#include "dns.h" + +static LDAP* ldap_con; +static sigjmp_buf stack_context; + +static struct { + char ldaphosts[256]; + const char* basedn; + char binddn[256]; + char bindpwd[16]; + struct timeval timeout; + int verbose; + int initialized; +} options; + +struct zonerecord { + char zonedn[256]; + char zonename[64]; + char class[16]; + char type[16]; + char adminmailbox[64]; + char zonemaster[64]; + unsigned long serial, refresh, retry, expire, minimum; + int ttl; + int timestamp; +}; + +struct resourcerecord { + char qualifieddomainname[256]; + char class[16]; + char type[16]; + char ipaddr[8][4]; + int numipaddrs; + char cname[256]; + unsigned int preference; + int ttl; + int timestamp; + int additionalinfo; + struct resourcerecord* next; +}; + +enum { ASKLDAP_RETRY = 1, ASKLDAP_RETURN = 2, ASKLDAP_RECONNECT = 3 }; + +static +void assert_ldap(int err) +{ + static int retries; + switch (err) { + case LDAP_SUCCESS: + return; + case LDAP_TIMELIMIT_EXCEEDED: + fprintf(stderr, "Warning: %s\n", ldap_err2string(err)); + retries++; + if (retries<3) + siglongjmp(stack_context, ASKLDAP_RETRY); + retries = 0; + siglongjmp(stack_context, ASKLDAP_RETURN); + case LDAP_TIMEOUT: + case LDAP_NO_SUCH_OBJECT: + fprintf(stderr, "Warning: %s\n", ldap_err2string(err)); + siglongjmp(stack_context, ASKLDAP_RETURN); + case LDAP_BUSY: + case LDAP_UNAVAILABLE: + case LDAP_UNWILLING_TO_PERFORM: + case LDAP_SERVER_DOWN: + fprintf(stderr, "Warning: %s\n", ldap_err2string(err)); + siglongjmp(stack_context, ASKLDAP_RECONNECT); + default: + fprintf(stderr, "Fatal error: %s\n", ldap_err2string(err)); +#ifdef _DEBUG + abort(); +#else + exit(1); +#endif + } +} + +void free_domainrecords(struct resourcerecord* anchor) +{ + struct resourcerecord* ptr; + for (ptr = anchor; ptr; ptr = anchor) { + anchor = anchor->next; + alloc_free(ptr); + } +} + +static +void fill_resourcerecord(struct resourcerecord* rr, LDAPMessage* m, const char* zonename) +{ + BerElement* ber = NULL; + char* attr; + + byte_zero(rr, sizeof(struct resourcerecord)); + strcpy(rr->class, "IN"); + for (attr = ldap_first_attribute(ldap_con, m, &ber); attr; attr = ldap_next_attribute(ldap_con, m, ber)) { + struct berval** bvals = ldap_get_values_len(ldap_con, m, attr); + if (bvals && bvals[0] && bvals[0]->bv_len>0) { + if (strcasecmp(attr, "dnsdomainname")==0) { + char tmp[64]; + if (sscanf(bvals[0]->bv_val, "%64s", tmp)==1) { + if (zonename[0]!='\0') + snprintf(rr->qualifieddomainname, 256, "%s.%s", tmp, zonename); + else + strncpy(rr->qualifieddomainname, tmp, 256); + } + } else if (strcasecmp(attr, "dnstype")==0) { + if (sscanf(bvals[0]->bv_val, "%16s", rr->type)!=1) { + rr->type[0] = '\0'; + } + } else if (strcasecmp(attr, "dnsipaddr")==0) { + int k, ip[4]; + for (k = 0; bvals[k] && k < 8-rr->numipaddrs; k++) { + if (sscanf(bvals[k]->bv_val, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) { + rr->ipaddr[rr->numipaddrs][0] = (char)ip[0]; + rr->ipaddr[rr->numipaddrs][1] = (char)ip[1]; + rr->ipaddr[rr->numipaddrs][2] = (char)ip[2]; + rr->ipaddr[rr->numipaddrs][3] = (char)ip[3]; + rr->numipaddrs++; + } + } + } else if (rr->numipaddrs<8 && strcasecmp(attr, "dnscipaddr")==0) { + int ip[4]; + if (sscanf(bvals[0]->bv_val, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) { + rr->ipaddr[rr->numipaddrs][0] = (char)ip[0]; + rr->ipaddr[rr->numipaddrs][1] = (char)ip[1]; + rr->ipaddr[rr->numipaddrs][2] = (char)ip[2]; + rr->ipaddr[rr->numipaddrs][3] = (char)ip[3]; + rr->numipaddrs++; + } + } else if (strcasecmp(attr, "dnscname")==0) { + if (sscanf(bvals[0]->bv_val, "%256s", rr->cname)==1) { + int len = strlen(rr->cname); + if (rr->cname[len-1]!='.' && zonename[0]!='\0') { + strcat(rr->cname, "."); + strncat(rr->cname, zonename, 252-len); + strcat(rr->cname, "."); + } + } else { + rr->cname[0] = '\0'; + } + } else if (strcasecmp(attr, "dnsttl")==0) { + if (sscanf(bvals[0]->bv_val, "%d", &rr->ttl)!=1) + rr->ttl = 0; + } else if (strcasecmp(attr, "dnstimestamp")==0) { + if (sscanf(bvals[0]->bv_val, "%d", &rr->timestamp)!=1) + rr->timestamp = 0; + } else if (strcasecmp(attr, "dnspreference")==0) { + if (sscanf(bvals[0]->bv_val, "%u", &rr->preference)!=1) + rr->preference = 1; + } + } + ldap_value_free_len(bvals); + } +} + +static +void fill_zonerecord(struct zonerecord* zone, LDAPMessage* m) +{ + BerElement* ber = NULL; + char* attr; + + byte_zero(zone, sizeof(struct zonerecord)); + strcpy(zone->class, "IN"); + for (attr = ldap_first_attribute(ldap_con, m, &ber); attr; attr = ldap_next_attribute(ldap_con, m, ber)) { + struct berval** bvals = ldap_get_values_len(ldap_con, m, attr); + if (bvals && bvals[0] && bvals[0]->bv_len>0) { + if (strcasecmp(attr, "dnstype")==0) { + if (sscanf(bvals[0]->bv_val, "%16s", zone->type)!=1) + zone->type[0] = '\0'; + } else if (strcasecmp(attr, "dnsserial")==0) { + if (sscanf(bvals[0]->bv_val, "%lu", &zone->serial)!=1) + zone->serial = 0; + } else if (strcasecmp(attr, "dnsrefresh")==0) { + if (sscanf(bvals[0]->bv_val, "%lu", &zone->refresh)!=1) + zone->refresh = 0; + } else if (strcasecmp(attr, "dnsretry")==0) { + if (sscanf(bvals[0]->bv_val, "%lu", &zone->retry)!=1) + zone->retry = 0; + } else if (strcasecmp(attr, "dnsexpire")==0) { + if (sscanf(bvals[0]->bv_val, "%lu", &zone->expire)!=1) + zone->expire = 0; + } else if (strcasecmp(attr, "dnsminimum")==0) { + if (sscanf(bvals[0]->bv_val, "%lu", &zone->minimum)!=1) + zone->minimum = 0; + } else if (strcasecmp(attr, "dnsadminmailbox")==0) { + if (sscanf(bvals[0]->bv_val, "%64s", zone->adminmailbox)!=1) + zone->adminmailbox[0] = '\0'; + } else if (strcasecmp(attr, "dnszonemaster")==0) { + if (sscanf(bvals[0]->bv_val, "%64s", zone->zonemaster)!=1) + zone->zonemaster[0] = '\0'; + } else if (strcasecmp(attr, "dnsttl")==0) { + if (sscanf(bvals[0]->bv_val, "%d", &zone->ttl)!=1) + zone->ttl = 0; + } else if (strcasecmp(attr, "dnstimestamp")==0) { + if (sscanf(bvals[0]->bv_val, "%d", &zone->timestamp)!=1) + zone->timestamp = 0; + } else if (strcasecmp(attr, "dnszonename")==0) { + if (sscanf(bvals[0]->bv_val, "%s", zone->zonename)!=1) + zone->zonename[0] = '\0'; + } + } + ldap_value_free_len(bvals); + } +} + +static +int find_ipaddr(const char* queryname, char ip[4]) +{ + static char *rrattrs[] = { "dnsipaddr", "dnscipaddr", 0 }; + LDAPMessage* res = NULL; + LDAPMessage* m; + int ret = 0; + char filter[256], domainname[64]; + const char *zonename = queryname; + domainname[0] = '\0'; + while (*zonename) { + int len = snprintf(filter, 256, "(&(dnszonename=%s", zonename); + if (filter[len-1]=='.') + filter[len-1] = '\0'; + strncat(filter, ")(objectclass=dnszone)(dnsclass=IN))", 256-len); + assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); + if (m = ldap_first_entry(ldap_con, res)) { + char* zonedn = ldap_get_dn(ldap_con, m); + if (ldap_next_entry(ldap_con, m)) + printf("Warning: ambigous zonename for %s in %s\n", zonename, zonedn); + if (domainname[0]!='\0') { + len = strlen(domainname); + if (domainname[len-1]=='.') + domainname[len-1] = '\0'; + snprintf(filter, 256, "(&(|(dnsdomainname=%s)(dnscname=%s))(objectclass=dnsrrset)(dnsclass=IN)(|(dnsipaddr=*)(dnscipaddr=*)))", domainname, domainname); + } else { + strcpy(filter, "(&(!(dnsdomainname=*))(objectclass=dnsrrset)(dnsclass=IN)(|(dnsipaddr=*)(dnscipaddr=*)))"); + } + ldap_msgfree(res); + assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); + if (m = ldap_first_entry(ldap_con, res)) { + struct resourcerecord rr; + fill_resourcerecord(&rr, m, ""); + if (rr.numipaddrs>0) { + rr.numipaddrs = rand()%rr.numipaddrs; + ip[0] = rr.ipaddr[rr.numipaddrs][0]; + ip[1] = rr.ipaddr[rr.numipaddrs][1]; + ip[2] = rr.ipaddr[rr.numipaddrs][2]; + ip[3] = rr.ipaddr[rr.numipaddrs][3]; + ret = 1; + } + } + ldap_memfree(zonedn); + ldap_msgfree(res); res = NULL; + if (ret) + return 1; + break; + } + while (*zonename && *zonename!='.') { + domainname[zonename-queryname] = *zonename; + zonename++; + } + domainname[zonename-queryname] = *zonename; + if (*zonename=='.') { + zonename++; + domainname[zonename-queryname] = '\0'; + } + } + /* sometimes the queryname resolves directly as cname in some other records */ + snprintf(filter, 256, "(&(dnscname=%s)(objectclass=dnsrrset)(dnsclass=IN)(|(dnsipaddr=*)(dnscipaddr=*)))", queryname); + assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); + if (m = ldap_first_entry(ldap_con, res)) { + struct resourcerecord rr; + fill_resourcerecord(&rr, m, ""); + if (rr.numipaddrs>0) { + rr.numipaddrs = rand()%rr.numipaddrs; + ip[0] = rr.ipaddr[rr.numipaddrs][0]; + ip[1] = rr.ipaddr[rr.numipaddrs][1]; + ip[2] = rr.ipaddr[rr.numipaddrs][2]; + ip[3] = rr.ipaddr[rr.numipaddrs][3]; + ret = 1; + } + } + ldap_msgfree(res); + return ret; +} + +static +struct resourcerecord* find_reverserecord(const char* queryname, int ip[4]) +{ + static char *rrattrs[] = { "dnstype", "dnsdomainname", "dnscname", "dnsttl", 0 }; + LDAPMessage* res = NULL; + struct resourcerecord* rr = NULL; + LDAPMessage* m; + char filter[256]; + snprintf(filter, 256, "(&(dnscipaddr=%u.%u.%u.%u)(objectclass=dnsrrset)(dnsclass=IN))", ip[0], ip[1], ip[2], ip[3]); + assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); + if (m = ldap_first_entry(ldap_con, res)) { + char* rrsetdn = ldap_get_dn(ldap_con, m); + char** explodedn = NULL; + + rr = (void*)alloc(sizeof(struct resourcerecord)); + fill_resourcerecord(rr, m, ""); + if (ldap_next_entry(ldap_con, m)) + printf("Warning: ambigous IP-address for %u.%u.%u.%u in dn: %s\n", ip[0], ip[1], ip[2], ip[3], rrsetdn); + explodedn = ldap_explode_dn(rrsetdn, 0); + if (explodedn[0]) { + static char *zoneattrs[] = { "dnszonename", 0 }; + char zonedn[256]; + int i, len = 0; + struct zonerecord zone; + + zonedn[0] = '\0'; + for (i = 1; explodedn[i]; i++) + len += snprintf(zonedn+len, 256-len, "%s,", explodedn[i]); + zonedn[len-1] = '\0'; + ldap_msgfree(res); + assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, "(objectclass=dnszone)", zoneattrs, 0, &options.timeout, &res)); + m = ldap_first_entry(ldap_con, res); + if (m==NULL) + printf("Error: parent dn: %s not found for %s\n", zonedn, rrsetdn); + fill_zonerecord(&zone, m); + len = strlen(rr->qualifieddomainname); + if (len==0) { + len = strlen(rr->cname); + if (rr->cname[len-1]!='.') { + strcat(rr->cname, "."); + strncat(rr->cname, zone.zonename, 252-len); + } + } else { + /* in those situations where a dnsrrset + * defines something like MX or NS for a zone + * and also sets a canonical name for the + * service. */ + snprintf(rr->cname, 256, "%s.%s", rr->qualifieddomainname, zone.zonename); + } + strcpy(rr->type, "PTR"); + strncpy(rr->qualifieddomainname, queryname, 256); + } + ldap_memfree(rrsetdn); + ldap_value_free(explodedn); + } + ldap_msgfree(res); + return rr; +} + +static +struct resourcerecord* read_domainrecords(const char* zonedn, const char* domainname, const char* zonename) +{ + static char *rrattrs[] = { "dnsdomainname", "dnstype", "dnsttl", "dnscname", "dnsipaddr", "dnscipaddr", "dnstimestamp", "dnspreference", 0 }; + LDAPMessage* res = NULL; + LDAPMessage* m; + char filter[256]; + struct resourcerecord *prev, *anchor = NULL; + + if (domainname[0]) { + if (strstr(zonename, "in-addr.arpa")) { + unsigned int ip[4]; + char queryname[256]; + snprintf(queryname, 256, "%s.%s", domainname, zonename); + if (sscanf(queryname, "%3u.%3u.%3u.%3u", &ip[3], &ip[2], &ip[1], &ip[0])!=4) + return NULL; + snprintf(filter, 256, "(&(dnsipaddr=%u.%u.%u.%u)(objectclass=dnsrrset)(dnsclass=IN))", ip[0], ip[1], ip[2], ip[3]); + assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); + if (m = ldap_first_entry(ldap_con, res)) { + struct resourcerecord* rr; + rr = (void*)alloc(sizeof(struct resourcerecord)); + fill_resourcerecord(rr, m, zonename); + strncpy(rr->qualifieddomainname, queryname, 256); + ldap_msgfree(res); + return rr; + } else { + /* ipaddr not in our baliwick, search the whole tree for canonical ipaddr */ + ldap_msgfree(res); + return find_reverserecord(queryname, ip); + } + } else { + int i; + for (i = 0; domainname[i]; i++) { + snprintf(filter, 256, (i==0 ? "(&(dnsdomainname=%s)(objectclass=dnsrrset)(dnsclass=IN))" : + "(&(dnsdomainname=\\*.%s)(objectclass=dnsrrset)(dnsclass=IN))"), &domainname[i]); + assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); + if (ldap_count_entries(ldap_con, res)>0) + break; + while (domainname[i] && domainname[i]!='.') + i++; + } + } + } else { + snprintf(filter, 256, "(&(!(dnsdomainname=*))(objectclass=dnsrrset)(dnsclass=IN))"); + assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); + } + for (m = ldap_first_entry(ldap_con, res); m; m = ldap_next_entry(ldap_con, m)) { + struct resourcerecord* rr; + rr = (void*)alloc(sizeof(struct resourcerecord)); + fill_resourcerecord(rr, m, zonename); + snprintf(rr->qualifieddomainname, 256, "%s%s%s", domainname, domainname[0] ? "." : "", zonename); + if (anchor==NULL) { + prev = anchor = rr; + } else { + prev->next = rr; + prev = rr; + } + if (options.verbose&1) + printf("\trr: %s %s\n", domainname, rr->type); + } + ldap_msgfree(res); + return anchor; +} + +static +int read_dnszone(struct zonerecord* zone, const char* zonename) +{ + static char *zoneattrs[] = { "dnszonename", "dnstype", "dnsserial", "dnsrefresh", "dnsretry", "dnsexpire", "dnsminimum", "dnszonemaster", "dnsadminmailbox", "dnsttl", "dnstimestamp", 0 }; + LDAPMessage* res = NULL; + LDAPMessage* m; + char* dn; + char filter[256]; + + snprintf(filter, 256, "(&(dnszonename=%s)(objectclass=dnszone)(dnsclass=IN))", zonename); + assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, zoneattrs, 0, &options.timeout, &res)); + m = ldap_first_entry(ldap_con, res); + if (m==NULL) { + ldap_msgfree(res); + return 0; + } + dn = ldap_get_dn(ldap_con, m); + fill_zonerecord(zone, m); + m = ldap_next_entry(ldap_con, m); + if (m) { + char* otherdn = ldap_get_dn(ldap_con, m); + printf("Warning: ambigous zonename found in dn: %s and dn: %s\n", dn, otherdn); + ldap_memfree(otherdn); + } + strncpy(zone->zonedn, dn, 256); + ldap_memfree(dn); + ldap_msgfree(res); + return 1; +} + +static +void djb_name(const char* dotname, char* djbname) +{ + const char* c = dotname; + int i, k; + for (i = 0; *c; c++) { + k = i; + while (*c!='.') { + k++; + djbname[k] = *c; + if (*c=='\0') { + djbname[i] = k-i-1; + return; + } + c++; + } + djbname[i] = k-i; + i = k+1; + } + djbname[i] = '\0'; +} + +static +void djb_type(const char* dottype, char djbtype[2]) +{ + djbtype[0] = '\0'; + if (strcasecmp(dottype, "A")==0) + djbtype[1] = 001; + else if (strcasecmp(dottype, "NS")==0) + djbtype[1] = 002; + else if (strcasecmp(dottype, "CNAME")==0) + djbtype[1] = 005; + else if (strcasecmp(dottype, "SOA")==0) + djbtype[1] = 006; + else if (strcasecmp(dottype, "PTR")==0) + djbtype[1] = 014; + else if (strcasecmp(dottype, "MX")==0) + djbtype[1] = 017; + else if (strcasecmp(dottype, "TXT")==0) + djbtype[1] = 020; +} + +static +void split_djbstyle(const char* djbname, char* domainname, char* zonename, int offset) +{ + int i, k, m = 0, n = 0; + for (i = *djbname; i; i = *++djbname) { + if (offset>0) { + offset--; + for (k = m; k0 ? m-1 : 0] = '\0'; + zonename[n>0 ? n-1 : 0] = '\0'; +} + +static +void build_response_section(struct resourcerecord *rr, char qtype[2], int section) +{ + char djbname[256], djbtype[2]; + djb_name(rr->qualifieddomainname, djbname); + djb_type(rr->type, djbtype); + if (byte_equal(djbtype, 2, DNS_T_A)) { + if (byte_equal(qtype, 2, DNS_T_A) || byte_equal(qtype, 2, DNS_T_ANY)) { + response_rstart(djbname, djbtype, rr->ttl); + response_addbytes(rr->ipaddr[rand()%rr->numipaddrs], 4); + response_rfinish(section); + } + } else if (byte_equal(djbtype, 2, DNS_T_CNAME)) { + response_rstart(djbname, djbtype, rr->ttl); + djb_name(rr->cname, djbname); + response_addname(djbname); + response_rfinish(section); + } else if (byte_equal(djbtype, 2, DNS_T_NS)) { + if (byte_equal(qtype, 2, DNS_T_NS) || byte_equal(qtype, 2, DNS_T_ANY)) { + response_rstart(djbname, djbtype, rr->ttl); + if (rr->cname[0]) { + djb_name(rr->cname, djbname); + response_addname(djbname); + rr->additionalinfo = 1; + } else { + response_addbytes(rr->ipaddr[rand()%rr->numipaddrs], 4); + } + response_rfinish(section); + } + } else if (byte_equal(djbtype, 2, DNS_T_PTR)) { + response_rstart(djbname, djbtype, rr->ttl); + djb_name(rr->cname, djbname); + response_addname(djbname); + response_rfinish(section); + } else if (byte_equal(djbtype, 2, DNS_T_MX)) { + if (byte_equal(qtype, 2, DNS_T_MX) || byte_equal(qtype, 2, DNS_T_ANY)) { + char tmp[2]; + response_rstart(djbname, djbtype, rr->ttl); + tmp[0] = rr->preference/0x100; + tmp[1] = rr->preference%0x100; + response_addbytes(tmp, 2); + if (rr->cname[0]) { + djb_name(rr->cname, djbname); + response_addname(djbname); + rr->additionalinfo = 1; + } else { + response_addbytes(rr->ipaddr[rand()%rr->numipaddrs], 4); + } + response_rfinish(section); + } + } +} + +static +void build_soa_section(struct zonerecord *zone, int section) +{ + time_t now; + char defaultsoa[20]; + char djbname[256]; + char zonesoa[20]; + unsigned long tmp; + time(&now); + djb_name(zone->zonename, djbname); + response_rstart(djbname, DNS_T_SOA, zone->ttl); + djb_name(zone->zonemaster, djbname); + response_addname(djbname); + djb_name(zone->adminmailbox, djbname); + response_addname(djbname); + uint32_pack_big(defaultsoa, now); + if (byte_equal(defaultsoa,4,"\0\0\0\0")) + defaultsoa[3] = 1; + byte_copy(defaultsoa + 4, 16, "\0\0\100\000\0\0\010\000\0\020\000\000\0\0\012\000"); + if (zone->serial==0) + uint32_unpack_big(defaultsoa, &tmp); + else + tmp = zone->serial; + uint32_pack_big(zonesoa, tmp); + if (zone->refresh==0) + uint32_unpack_big(defaultsoa+4, &tmp); + else + tmp = zone->refresh; + uint32_pack_big(zonesoa+4, tmp); + if (zone->retry==0) + uint32_unpack_big(defaultsoa+8, &tmp); + else + tmp = zone->retry; + uint32_pack_big(zonesoa+8, tmp); + if (zone->expire==0) + uint32_unpack_big(defaultsoa+12, &tmp); + else + tmp = zone->expire; + uint32_pack_big(zonesoa+12, tmp); + if (zone->minimum==0) + uint32_unpack_big(defaultsoa+16, &tmp); + else + tmp = zone->minimum; + uint32_pack_big(zonesoa+16, tmp); + response_addbytes(zonesoa, 20); + response_rfinish(section); +} + +static +void build_additional_section(struct resourcerecord *rr) +{ + char djbname[256], ip[4]; + if (rr->additionalinfo && find_ipaddr(rr->cname, ip)) { + djb_name(rr->cname, djbname); + response_rstart(djbname, DNS_T_A, rr->ttl); + response_addbytes(ip, 4); + response_rfinish(RESPONSE_ADDITIONAL); + } +} + +static +int connect_and_bind() +{ + ldap_con = ldap_init(options.ldaphosts, LDAP_PORT); + if (ldap_simple_bind_s(ldap_con, options.binddn, options.bindpwd)==LDAP_SUCCESS) { + printf("Connected to %s as \"%s\"\n", options.ldaphosts, options.binddn); + return 1; + } + ldap_con = NULL; + return 0; +} + +int askldap_query(const char* djbdomainname, char qtype[2]) +{ + int offset; + char domainname[64], zonename[64]; + struct zonerecord zoneinfo; + int answer_ok = 0, flagsoa = 0, flagns = 0; + if (!options.initialized) + return 0; + switch (sigsetjmp(stack_context, 1)) { + default: + if (ldap_con==NULL && !connect_and_bind()) + return answer_ok; + break; + case ASKLDAP_RECONNECT: + if (connect_and_bind()) + break; + return answer_ok; + case ASKLDAP_RETURN: + return answer_ok; + } + for (offset = 0; offset<32; offset++) { + struct resourcerecord *rransw, *rrauth, *rr; + + split_djbstyle(djbdomainname, domainname, zonename, offset); + if (zonename[0]=='\0') return 0; + if (!read_dnszone(&zoneinfo, zonename)) + continue; + rransw = read_domainrecords(zoneinfo.zonedn, domainname, zonename); + rrauth = NULL; + if (offset==0) { + /* query is in our bailiwick */ + if (byte_equal(qtype, 2, DNS_T_ANY) || byte_equal(qtype, 2, DNS_T_SOA)) { + build_soa_section(&zoneinfo, RESPONSE_ANSWER); + flagsoa = 1; + } + for (rr = rransw; rr; rr = rr->next) { + build_response_section(rr, qtype, RESPONSE_ANSWER); + answer_ok = 1; + } + if (!flagsoa) { + build_soa_section(&zoneinfo, RESPONSE_AUTHORITY); + flagsoa = 1; + } + if (!byte_equal(qtype, 2, DNS_T_ANY) && !byte_equal(qtype, 2, DNS_T_NS)) { + for (rr = rransw; rr; rr = rr->next) + if (strcmp(rr->type, "NS")==0) { + build_response_section(rr, DNS_T_NS, RESPONSE_AUTHORITY); + flagns = 1; + } + } + } else { + for (rr = rransw; rr; rr = rr->next) { + if (strcmp(rr->type, "NS")==0) { + build_response_section(rr, qtype, RESPONSE_AUTHORITY); + flagns = 1; + } + } + if (!flagns) { + for (rr = rransw; rr; rr = rr->next) { + build_response_section(rr, qtype, RESPONSE_ANSWER); + answer_ok = 1; + } + if (answer_ok) { + rrauth = read_domainrecords(zoneinfo.zonedn, "", zonename); + } else { + build_soa_section(&zoneinfo, RESPONSE_AUTHORITY); + flagsoa = 1; + } + } + for (rr = rrauth; rr; rr = rr->next) { + if (strcmp(rr->type, "NS")==0) { + build_response_section(rr, DNS_T_NS, RESPONSE_AUTHORITY); + flagns = 1; + } + } + } + for (rr = rransw; rr; rr = rr->next) + build_additional_section(rr); + for (rr = rrauth; rr; rr = rr->next) + build_additional_section(rr); + free_domainrecords(rransw); + free_domainrecords(rrauth); + break; + } + return answer_ok || flagsoa || flagns; +} + +void askldap_init(const char* ldaphost, const char* basedn, const char* binddn, const char* passwd) +{ + strncpy(options.ldaphosts, ldaphost, 256); + options.basedn = basedn; + if (binddn) strncpy(options.binddn, binddn, 256); + if (passwd) strncpy(options.bindpwd, passwd, 16); + /* LDAP timeout is hardcoded to 2/10 second. + * This must be enough because bindoperations usually + * timeout after one second and here we usually have to + * send five queries to the LDAP-server */ + options.timeout.tv_sec = 1; + options.timeout.tv_usec = 200000; + options.verbose = 0; + options.initialized = 1; + connect_and_bind(); +} + diff -Naur djbdns-1.05.orig/askldap.h djbdns-1.05/askldap.h --- djbdns-1.05.orig/askldap.h Thu Jan 1 01:00:00 1970 +++ djbdns-1.05/askldap.h Tue Aug 13 14:30:22 2002 @@ -0,0 +1,10 @@ +/* Patch for tinydns to pass DNS-query to LDAP in favour of a cdb lookup. + * $Id$ + * Copyright 2002 + */ + +extern +int askldap_query(const char* djbdomainname, char qtype[2]); + +extern +void askldap_init(const char* ldaphost, const char* basedn, const char* binddn, const char* passwd); diff -Naur djbdns-1.05.orig/ldap.lib djbdns-1.05/ldap.lib --- djbdns-1.05.orig/ldap.lib Thu Jan 1 01:00:00 1970 +++ djbdns-1.05/ldap.lib Tue Aug 13 14:29:53 2002 @@ -0,0 +1 @@ +-lldap -llber diff -Naur djbdns-1.05.orig/server.c djbdns-1.05/server.c --- djbdns-1.05.orig/server.c Sun Feb 11 22:11:45 2001 +++ djbdns-1.05/server.c Tue Aug 13 14:29:15 2002 @@ -11,6 +11,7 @@ #include "qlog.h" #include "response.h" #include "dns.h" +#include "askldap.h" extern char *fatal; extern char *starting; @@ -79,6 +80,7 @@ return 0; } + int main() { char *x; @@ -90,6 +92,19 @@ if (!ip4_scan(x,ip)) strerr_die3x(111,fatal,"unable to parse IP address ",x); + x = env_get("LDAPHOSTS"); + if (x) { + char *basedn = env_get("LDAPBASEDN"); + char *binddn = env_get("LDAPBINDDN"); + char *bindpwd = env_get("LDAPPASSWD"); + if (basedn) + askldap_init(x, basedn, binddn, bindpwd); + if (bindpwd) { + int len = str_len(bindpwd); + while (len) bindpwd[--len] = 'x'; + } + } + udp53 = socket_udp(); if (udp53 == -1) strerr_die2sys(111,fatal,"unable to create UDP socket: "); diff -Naur djbdns-1.05.orig/tdlookup.c djbdns-1.05/tdlookup.c --- djbdns-1.05.orig/tdlookup.c Sun Feb 11 22:11:45 2001 +++ djbdns-1.05/tdlookup.c Tue Aug 13 14:29:29 2002 @@ -8,6 +8,7 @@ #include "dns.h" #include "seek.h" #include "response.h" +#include "askldap.h" static int want(const char *owner,const char type[2]) { @@ -285,10 +286,13 @@ char key[6]; tai_now(&now); + if (askldap_query(q, qtype)) + return 1; + fd = open_read("data.cdb"); if (fd == -1) return 0; cdb_init(&c,fd); - + byte_zero(clientloc,2); key[0] = 0; key[1] = '%'; ldap2dns-0.3.1/dns.schema0100664000100100010010000000556207526175131014144 0ustar jriefjrief# schema for DNS data # include this file into Your slapd.conf for openldap-2.0.x # $Id: dns.schema,v 1.9 2001/11/06 08:01:51 config Exp $ attributetype ( 1.3.6.1.4.1.7222.1.4.1 NAME 'dnszonename' SUP name ) attributetype ( 1.3.6.1.4.1.7222.1.4.2 NAME 'dnsserial' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7222.1.4.3 NAME 'dnsrefresh' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7222.1.4.4 NAME 'dnsretry' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7222.1.4.5 NAME 'dnsexpire' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7222.1.4.6 NAME 'dnsminimum' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7222.1.4.7 NAME 'dnsadminmailbox' SUP name ) attributetype ( 1.3.6.1.4.1.7222.1.4.8 NAME 'dnszonemaster' SUP name ) attributetype ( 1.3.6.1.4.1.7222.1.4.9 NAME 'dnstype' SUP name ) attributetype ( 1.3.6.1.4.1.7222.1.4.10 NAME 'dnsclass' SUP name ) attributetype ( 1.3.6.1.4.1.7222.1.4.11 NAME 'dnsdomainname' SUP name ) attributetype ( 1.3.6.1.4.1.7222.1.4.12 NAME 'dnsipaddr' EQUALITY numericStringMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} ) attributetype ( 1.3.6.1.4.1.7222.1.4.13 NAME 'dnscipaddr' EQUALITY numericStringMatch SUBSTR numericStringSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{16} ) attributetype ( 1.3.6.1.4.1.7222.1.4.14 NAME 'dnscname' SUP name ) attributetype ( 1.3.6.1.4.1.7222.1.4.15 NAME 'dnspreference' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7222.1.4.16 NAME 'dnsrr' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7222.1.4.17 NAME 'dnsttl' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7222.1.4.18 NAME 'dnstimestamp' SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) attributetype ( 1.3.6.1.4.1.7222.1.4.21 NAME 'NIChandle' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} ) attributetype ( 1.3.6.1.4.1.7222.1.4.22 NAME 'TIShandle' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{16} ) objectclass ( 1.3.6.1.4.1.7222.1.4.19 NAME 'dnszone' MUST ( objectclass $ cn ) MAY ( dnszonename $ dnsserial $ dnsrefresh $ dnsretry $ dnsexpire $ dnsminimum $ dnsadminmailbox $ dnszonemaster $ dnstype $ dnsclass $ dnsttl $ dnstimestamp $ owner $ NIChandle $ TIShandle ) ) objectclass ( 1.3.6.1.4.1.7222.1.4.20 NAME 'dnsrrset' SUP dnszone MUST ( objectclass $ cn ) MAY ( dnsdomainname $ dnsrr $ dnsclass $ dnstype $ dnsipaddr $ dnscipaddr $ dnscname $ dnspreference $ dnsttl $ dnstimestamp $ owner ) ) ldap2dns-0.3.1/example.ldif0100664000100100010010000000146107213677502014465 0ustar jriefjriefdn: ou=dns,o=myorg objectclass: organizationalUnit ou: dns userpassword: dnsadmin dn: cn=corp.local,ou=dns,o=myorg objectclass: DNSzone cn: corp.local DNSzonename: corp.local DNSserial: 12345 DNSrefresh: 10800 DNSretry: 3600 DNSexpire: 3600000 DNSminimum: 86400 DNSadminmailbox: domainmaster.myorg DNSzonemaster: ldap.myorg dn: cn=mail,cn=corp.local,ou=dns,o=myorg objectclass: DNSrrset cn: mail DNScname: mail DNStype: mx DNSipaddr: 17.19.21.23 dn: cn=ns1,cn=corp.local,ou=dns,o=myorg objectclass: DNSrrset cn: ns1 DNScname: ns1 DNStype: ns DNSipaddr: 17.19.23.24 dn: cn=ns2,cn=corp.local,ou=dns,o=myorg objectclass: DNSrrset cn: ns2 DNScname: ns2 DNStype: ns DNSipaddr: 17.19.23.25 dn: cn=www,cn=corp.local,ou=dns,o=myorg objectclass: DNSrrset cn: www DNSdomainname: www DNStype: a DNSipaddr: 17.19.23.30 ldap2dns-0.3.1/import.pl0100775000100100010010000002002107216140255014026 0ustar jriefjrief#!/usr/bin/perl # Script to import data from DNS into LDAP # Copyright 2000, Jacob Rief # $Id: import.pl,v 1.24 2000/12/14 12:44:29 jrief Exp $ ###### configure this ###### # remember to allow zone transfers from Your nameserver $LDAPHOST = "ldap.myorg.com"; $LDAPBINDDN = "ou=dns,o=myorg"; $LDAPPASSWD = "secret"; $NAMESERVER = "ns1.myorg.com"; $BASEDN = "ou=dns,o=myorg"; $FULL_QUALIFIED_NAME = 0; ###### don't edit below this line ###### use Net::DNS; use Net::LDAP; $ldap = Net::LDAP->new($LDAPHOST) or die "Can't connect to LDAP server"; $mesg = $ldap->bind( dn => $LDAPBINDDN, password => $LDAPPASSWD ); die "Unable to bind to LDAP ", $mesg->error if ($mesg->code); @domains; while (<>) { chomp; $_ = lc; if (/primary\s+([0-9A-Za-z._+-]+)\s+/) { push(@domains, $1); } } if ($#domains>=0) { @domains = sort(@domains); for ($i = 1; $i<=$#domains; $i++) { if ($domains[$i-1] eq $domains[$i]) { print "Warning: removing double entry for zone: $domains[$i]\n"; splice(@domains, $i, 1); } } print "Adding ". ($#domains+1) ." zones to LDAP server\n"; foreach(@domains) { read_zone($_); } } else { print "No domain added to LDAP server\n"; } sub add_attrs { my ($attr, $zonename) = @_; # correct DNScname if (defined $$attr{'DNScname'}) { # check if DNScname is a real name if ($$attr{'DNScname'} =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) { $$attr{'DNSipaddr'} = "$1.$2.$3.$4"; undef $$attr{'DNScname'}; } } my ($tail); if ($$attr{'DNSdomainname'} eq $zonename) { $tail = ""; } else { split /\.$zonename/, $$attr{'DNSdomainname'}; die "Corrupt DNSdomainname" unless (defined @_[0]); $tail = @_[0]; } if ($FULL_QUALIFIED_NAME) { $$attr{'DNSdomainname'} = "$zonename." if ($tail eq ""); $$attr{'DNSdomainname'} = "$tail.$zonename." unless ($tail eq ""); $$attr{'DNScname'} .= "." if (defined $$attr{'DNScname'}); } else { $$attr{'DNSdomainname'} = "$tail"; if (defined $$attr{'DNScname'}) { split /\.$zonename/, $$attr{'DNScname'}; $$attr{'DNScname'} = @_[0] if (defined @_[0]); } } my $rrdn; if ($$attr{'DNStype'} eq "A") { # A records are multivalued, use one rrset for all ipaddresses $$attr{'cn'} = "A:$tail"; $rrdn = "cn=$$attr{'cn'},cn=$zonename,$BASEDN"; $mesg = $ldap->search(base=>$rrdn, scope=>"base", filter => "(objectclass=DNSrrset)"); if ($mesg->count==0) { $mesg = $ldap->add(dn=>$rrdn, attr=>list_attrs($attr)); die "Failed to add entry:", $rrdn, " ", $mesg->error if ($mesg->code); } else { $mesg = $ldap->modify(dn=>$rrdn, add=>{ 'DNSipaddr'=>$$attr{'DNSipaddr'} }); die "Failed to modify entry:", $rrdn, " ", $mesg->error if ($mesg->code); } } else { # All other records are siglevalued, use one rrset for each entry my $i = 0; do { $i++; $$attr{'cn'} = "$$attr{'DNStype'}$i:$tail"; $rrdn = "cn=$$attr{'cn'},cn=$zonename,$BASEDN"; $mesg = $ldap->search(base=>$rrdn, scope=>"base", filter=>"(objectclass=DNSrrset)"); } while ($mesg->count>0); if ($FULL_QUALIFIED_NAME) { $$attr{'DNScname'} = "$$attr{'DNStype'}$i.$zonename." unless defined $$attr{'DNScname'}; } else { $$attr{'DNScname'} = "$$attr{'DNStype'}$i" unless defined $$attr{'DNScname'}; } $mesg = $ldap->add(dn=>$rrdn, attr=>list_attrs($attr)); die "Failed to add entry:", $rrdn, " ", $mesg->error if ($mesg->code); } } sub list_attrs { my $attr = shift; my (@list, $key, $value); while (($key, $value) = each %$attr) { push(@list, $key => $value); } return \@list; } sub read_zone { my $zonename = shift; $res = new Net::DNS::Resolver; $res->nameservers($NAMESERVER); @zone = $res->axfr($zonename); while (!@zone) { print "Query failed for $zonename: ", $res->errorstring, ".\n"; if ($res->errorstring eq "couldn't connect") { print "Trying to reconnect\n"; sleep(10); @zone = $res->axfr($zonename); } else { return; } } print "---------- reading zone $zonename ----------\n"; foreach $rr (@zone) { $rr->print; if ($rr->type eq "SOA") { die "Invalid SOA record for ", $rr->name, " " unless ($rr->string =~ /^([0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9a-zA-Z_.+-]+)\s+([0-9a-zA-Z_.+-]+)\s+\((.*)\)/s); die "Corrupt SOA record for ", $rr->name, " " unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type); my %attr; $attr{'objectclass'} = "DNSzone"; $attr{'DNSzonename'} = lc $1; $attr{'DNSttl'} = $2; $attr{'DNSclass'} = $3; $attr{'DNStype'} = $4; $attr{'DNSzonemaster'} = lc $5; $attr{'DNSadminmailbox'} = lc $6; my $soa = $7; die "Invalid SOA fields for ", $zonename, " " unless ($soa =~ /\s*(\d+)\D*(\d+)\D*(\d+)\D*(\d+)\D*(\d+)\s*/s); $attr{'DNSserial'} = $1; $attr{'DNSrefresh'} = $2; $attr{'DNSretry'} = $3; $attr{'DNSexpire'} = $4; $attr{'DNSminimum'} = $5; $attr{'cn'} = $zonename; $mesg = $ldap->add(dn=>"cn=$zonename,$BASEDN", attr=>list_attrs(\%attr)); die "Failed to add entry:", $zonename, " ", $mesg->error if ($mesg->code); } elsif ($rr->type eq "A") { die "Invalid A record for ", $rr->name, " " unless ($rr->string =~ /^([0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9.]+)/); die "Corrupt A record for ", $rr->name, " " unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type && $5 eq $rr->address); next if $1 eq "localhost.$zonename"; my %attr; $attr{'objectclass'} = "DNSrrset"; $attr{'DNSdomainname'} = lc $1; $attr{'DNSttl'} = $2; $attr{'DNSclass'} = $3; $attr{'DNStype'} = $4; $attr{'DNSipaddr'} = $5; add_attrs(\%attr, $zonename); } elsif ($rr->type eq "MX") { die "Invalid MX record for ", $rr->name, " " unless ($rr->string =~ /^([0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+(\d+)\s+([0-9a-zA-Z_.+-]+)/); die "Corrupt MX record for ", $rr->name, " " unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type); my %attr; $attr{'objectclass'} = "DNSrrset"; $attr{'DNSdomainname'} = lc $1; $attr{'DNSttl'} = $2; $attr{'DNSclass'} = $3; $attr{'DNStype'} = $4; $attr{'DNSpreference'} = $5; $attr{'DNScname'} = lc $6; add_attrs(\%attr, $zonename); } elsif ($rr->type eq "NS") { die "Invalid NS record for ", $rr->name, " " unless ($rr->string =~ /^([0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9a-zA-Z_.+-]+)/); die "Corrupt NS record for ", $rr->name, " " unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type); my %attr; $attr{'objectclass'} = "DNSrrset"; $attr{'DNSdomainname'} = lc $1; $attr{'DNSttl'} = $2; $attr{'DNSclass'} = $3; $attr{'DNStype'} = $4; $attr{'DNScname'} = lc $5; add_attrs(\%attr, $zonename); } elsif ($rr->type eq "CNAME" || $rr->type eq "TXT") { die "Invalid ", $rr->type, " record for ", $rr->name, " " unless ($rr->string =~ /^([0-9a-zA-Z_.+-]+)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9a-zA-Z_.+-]+)/); die "Corrupt ", $rr->type, " record for ", $rr->name, " " unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type); my %attr; $attr{'objectclass'} = "DNSrrset"; $attr{'DNSdomainname'} = $1; $attr{'DNSttl'} = $2; $attr{'DNSclass'} = $3; $attr{'DNStype'} = $4; $attr{'DNScname'} = $5; add_attrs(\%attr, $zonename); } elsif ($rr->type eq "PTR") { die "Invalid PTR record for ", $rr->name, " " unless ($rr->string =~ /^([0-9.]+\.in-addr\.arpa)\.\s+(\d+)\s+(\w+)\s+(\w+)\s+([0-9a-zA-Z_.+-]+)/); die "Corrupt PTR record for ", $rr->name, " " unless ($1 eq $rr->name && $2 eq $rr->ttl && $3 eq $rr->class && $4 eq $rr->type); my %attr; $attr{'objectclass'} = "DNSrrset"; $attr{'DNSdomainname'} = "$1."; $attr{'DNSttl'} = $2; $attr{'DNSclass'} = $3; $attr{'DNStype'} = $4; $attr{'DNScname'} = $5; if ($attr{'DNSdomainname'} =~ /(\d+)\.(\d+)\.(\d+)\.(\d+)/) { $attr{'DNSipaddr'} = "$4.$3.$2.$1"; $attr{'cn'} = "PTR:$1"; # Only for C-level domains yet } else { die "Corrupt IP address for", $rr->name; } my $rrdn = "cn=$attr{'cn'},cn=$zonename,$BASEDN"; $mesg = $ldap->add(dn=>$rrdn, attr=>list_attrs(\%attr)); die "Failed to add entry:", $rrdn, " ", $mesg->error if ($mesg->code); } } } ldap2dns-0.3.1/index.html0100664000100100010010000000511307334466513014167 0ustar jriefjrief LDAP to DNS gateway

Download

Versiontar.gzrpmsrpmReleased
0.1.1ldap2dns2000-Sep-19
0.1.2ldap2dns2000-Sep-22
0.1.3ldap2dns2000-Sep-28
0.1.4ldap2dns2000-Oct-04
0.2.0ldap2dnsldap2dnsldap2dns2000-Dec-14
0.2.2ldap2dnsldap2dnsldap2dns2001-Feb-16
0.2.3ldap2dnsldap2dnsldap2dns2001-Mar-23
0.2.4ldap2dnsldap2dnsldap2dns2001-May-08
0.2.5ldap2dnsldap2dnsldap2dns2001-Jun-27
0.2.6ldap2dnsldap2dnsldap2dns2001-Aug-09
ldap2dns-0.3.1/ldap2dns.c0100660000100100010010000006715607522521410014043 0ustar jriefjrief/* * Create data from an LDAP directory service to be used for tinydns * $Id: ldap2dns.c,v 1.32 2002/08/02 15:19:36 jrief Exp $ * Copyright 2000 by Jacob Rief * License: GPL version 2 or later. See http://www.fsf.org for details */ #include #include #include #include #include #include #include #define UPDATE_INTERVALL 59 #define LDAP_CONF "/etc/ldap.conf" #define OUTPUT_DATA 1 #define OUTPUT_DB 2 #define MAXHOSTS 10 static char tinydns_textfile[256]; static char tinydns_texttemp[256]; static LDAP* ldap_con; static FILE* namedmaster; static FILE* namedzone; static FILE* tinyfile; static FILE* ldifout; static time_t time_now; static char* const* main_argv; static int main_argc; static void print_version(void) { printf("ldap2dns, version %s\n", VERSION); printf(" Copyright 2000 by Jacob Rief \n\n"); } static void die_ldap(int err) { fprintf(stderr, "Fatal error: %s\n", ldap_err2string(err)); exit(1); } static struct { char domainname[64]; char zonemaster[64]; char class[16]; char adminmailbox[64]; char serial[12]; char refresh[12]; char retry[12]; char expire[12]; char minimum[12]; char ttl[12]; char timestamp[20]; } zone; struct resourcerecord { char cn[64]; char dnsdomainname[64]; char class[16]; char type[16]; char ipaddr[256][32]; char cipaddr[32]; char cname[64]; char ttl[12]; char timestamp[20]; char preference[12]; #if defined DRAFT_RFC char rr[1024]; char aliasedobjectname[256]; char macaddress[32]; #endif }; static struct { char searchbase[128]; char binddn[128]; char hostname[MAXHOSTS][128]; int port[MAXHOSTS]; char password[128]; int usedhosts; int is_daemon; int update_iv; unsigned int output; int verbose; char ldifname[128]; char exec_command[128]; } options; static void die_exit(const char* message) { if (message) fprintf(stderr, "Fatal error: %s\n", message); else fprintf(stderr, "Fatal memory error\n"); exit(1); } static void set_datadir(void) { char* ev = getenv("TINYDNSDIR"); int len; tinydns_textfile[0] = '\0'; tinydns_texttemp[0] = '\0'; if (ev && (len = strlen(ev))<240) { strncpy(tinydns_textfile, ev, 240); strncpy(tinydns_texttemp, ev, 240); if (ev[len-1]!='/') { tinydns_textfile[len] = '/'; tinydns_texttemp[len] = '/'; } } strcat(tinydns_textfile, "data"); strcat(tinydns_texttemp, "data.temp"); } static void print_usage(void) { print_version(); printf("usage: ldap2dns[d] [-D binddn] [-b searchbase] [-o data|db] [-h host] [-p port] [-w password] [-L[filename]] [-u numsecs] [-v[v]] [-V]\n\n"); printf("ldap2dns connects to an LDAP server reads the DNS information stored in objectclasses\n" "\t\tDNSzone and DNSrrset and writes a file to be used by tinydns or named.\n" "\t\tldap2dnsd starts as background-job and continouesly updates DNS information.\n"); printf("options:\n"); printf(" -D binddn\tUse the distinguished name binddn to bind to the LDAP directory\n"); printf(" -w bindpasswd\tUse bindpasswd as the password for simple authentication\n"); printf(" -b Use searchbase as the starting point for the search instead of the default\n"); printf(" -o data\tGenerate a \"data\" file to be processed by tinydns-data\n"); printf(" -o db\tFor each zone generate a \".db\" file to be used by named\n"); printf(" -L[filename] Print output in LDIF format for reimport\n"); printf(" -h host\tHostname of LDAP server, defaults to localhost\n"); printf(" -p port\tPortnumber to connect to LDAP server, defaults to %d\n", LDAP_PORT); printf(" -u numsecs\tUpdate DNS data after numsecs. Defaults to %d if started as daemon.\n\t\t" "Important notice: data.cdb is rewritten only after DNSserial in DNSzone is increased.\n", UPDATE_INTERVALL); printf(" -e \"exec-cmd\" This command is executed after ldap2dns regenerated its data files\n"); printf(" -v\t\trun in verbose mode\n"); printf(" -vv\t\teven more verbose\n"); printf(" -V\t\tprint version and exit\n\n"); } static void parse_hosts(char* buf) { int i, port, k; char value[128], rest[512]; options.usedhosts = 0; for (i = 0; i=2) { strcpy(options.hostname[i], value); options.port[i] = port; options.usedhosts++; if (k==2) break; buf = rest; } else if ((k = sscanf(buf, "%128s %512[A-Za-z0-9 .:_+-]", value, rest))>=1) { strcpy(options.hostname[i], value); options.port[i] = LDAP_PORT; options.usedhosts++; if (k==1) break; buf = rest; } else break; } } static int parse_options() { extern char* optarg; extern int optind, opterr, optopt; char buf[256], value[128]; int len; FILE* ldap_conf,*fp; char* ev; strcpy(options.searchbase, ""); strcpy(options.hostname[0], "localhost"); options.port[0] = LDAP_PORT; if (ldap_conf = fopen(LDAP_CONF, "r")) { while(fgets(buf, 256, ldap_conf)!=0) { int i; if (sscanf(buf, "BASE %128s", value)==1) strcpy(options.searchbase, value); if (sscanf(buf, "HOST %512[A-Za-z0-9 .:_+-]", value)==1) parse_hosts(value); if (sscanf(buf, "PORT %d", &len)==1) for (i = 0; i0) { options.update_iv = len; } options.output = 0; ev = getenv("LDAP2DNS_OUTPUT"); if (ev) { if (strcmp(ev, "data")==0) options.output = OUTPUT_DATA; else if (strcmp(ev, "db")==0) options.output = OUTPUT_DB; } ev = getenv("LDAP2DNS_BINDDN"); if (ev) { strncpy(options.binddn, ev, 128); ev = getenv("LDAP2DNS_PASSWORD"); if (ev) strncpy(options.password, ev, 128); } options.verbose = 0; options.ldifname[0] = '\0'; strcpy(options.password, ""); strcpy(options.exec_command, ""); while ( (len = getopt(main_argc, main_argv, "b:D:e:h:o:p:u:V:v::w:L::"))>0 ) { if (optarg && strlen(optarg)>127) { fprintf(stderr, "argument %s too long\n", optarg); continue; } switch (len) { case 'b': strcpy(options.searchbase, optarg); break; case 'u': if (sscanf(optarg, "%d", &options.update_iv)!=1) options.update_iv = UPDATE_INTERVALL; if (options.update_iv<=0) options.update_iv = 1; break; case 'D': strcpy(options.binddn, optarg); break; case 'h': strcpy(options.hostname[0], optarg); options.usedhosts = 1; break; case 'L': if (optarg==NULL) strcpy(options.ldifname, "-"); else strcpy(options.ldifname, optarg); break; case 'o': if (strcmp(optarg, "data")==0) options.output |= OUTPUT_DATA; else if (strcmp(optarg, "db")==0) options.output |= OUTPUT_DB; break; case 'p': if (sscanf(optarg, "%d", &options.port[0])!=1) options.port[0] = LDAP_PORT; break; case 'v': if (optarg && optarg[0]=='v') options.verbose = 3; else options.verbose = 1; break; case 'V': print_version(); exit(0); case 'w': strcpy(options.password, optarg); memset(optarg, 'x', strlen(options.password)); break; case 'e': strcpy(options.exec_command, optarg); break; default: print_usage(); exit(1); } } if (options.is_daemon==0 && options.update_iv>0) options.is_daemon = 2; /* foreground daemon */ } static int expand_domainname(char target[64], const char* source, int slen) { if (slen>64) return 0; if (source[slen-1]=='.') { strncpy(target, source, slen-1); target[slen-1] = '\0'; return 1; } strncpy(target, source, slen); target[slen] = '\0'; if (zone.domainname[0]) { if (zone.domainname[0]!='.') strcat(target, "."); strcat(target, zone.domainname); return 1; } return 0; } static int expand_reverse(char target[64], const char* source) { } static void write_rr(struct resourcerecord* rr, int ipdx, int znix) { char ip[4]; char buf[4]; if (strcasecmp(rr->class, "IN")) return; if (strcasecmp(rr->type, "NS")==0) { if (tinyfile) { if (znix==0) { if (ipdx<=0 && rr->cipaddr[0]) { fprintf(tinyfile, "&%s::%s:%s:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp); if (rr->cname[0]) fprintf(tinyfile, "=%s:%s:%s:%s\n", rr->cname, rr->cipaddr, rr->ttl, rr->timestamp); if (ipdx==0) fprintf(tinyfile, "+%s:%s:%s:%s\n", rr->cname, rr->ipaddr[0], rr->ttl, rr->timestamp); } else if (ipdx<0) fprintf(tinyfile, "&%s::%s:%s:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp); else if (ipdx==0) fprintf(tinyfile, "&%s:%s:%s:%s:%s\n", rr->dnsdomainname, rr->ipaddr[0], rr->cname, rr->ttl, rr->timestamp); else if (ipdx>0 && rr->cname[0]) fprintf(tinyfile, "+%s:%s:%s:%s\n", rr->cname, rr->ipaddr[ipdx], rr->ttl, rr->timestamp); } else if (ipdx<=0) { fprintf(tinyfile, "&%s::%s:%s:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp); } } if (namedzone) { fprintf(namedzone, "%s.\tIN NS\t%s.\n", rr->dnsdomainname, rr->cname); if (ipdx>=0) fprintf(namedzone, "%s.\tIN A\t%s\n", rr->cname, rr->ipaddr[ipdx]); } } else if (strcasecmp(rr->type, "MX")==0) { if (tinyfile) { if (znix==0) { if (ipdx<=0 && rr->cipaddr[0]) { fprintf(tinyfile, "@%s::%s:%s:%s:%s\n", rr->dnsdomainname, rr->cname, rr->preference, rr->ttl, rr->timestamp); if (rr->cname[0]) fprintf(tinyfile, "=%s:%s:%s:%s\n", rr->cname, rr->cipaddr, rr->ttl, rr->timestamp); if (ipdx==0) fprintf(tinyfile, "+%s:%s:%s:%s\n", rr->cname, rr->ipaddr[0], rr->ttl, rr->timestamp); } else if (ipdx<0) fprintf(tinyfile, "@%s::%s:%s:%s:%s\n", rr->dnsdomainname, rr->cname, rr->preference, rr->ttl, rr->timestamp); else if (ipdx==0) fprintf(tinyfile, "@%s:%s:%s:%s:%s:%s\n", rr->dnsdomainname, rr->ipaddr[0], rr->cname, rr->preference, rr->ttl, rr->timestamp); else if (ipdx>0 && rr->cname[0]) fprintf(tinyfile, "+%s:%s:%s:%s\n", rr->cname, rr->ipaddr[ipdx], rr->ttl, rr->timestamp); } else if (ipdx<=0) { fprintf(tinyfile, "@%s::%s:%s:%s:%s\n", rr->dnsdomainname, rr->cname, rr->preference, rr->ttl, rr->timestamp); } } if (namedzone) { fprintf(namedzone, "%s.\tIN MX\t%s %s.\n", rr->dnsdomainname, rr->preference, rr->cname); if (ipdx>=0) fprintf(namedzone, "%s.\tIN A\t%s\n", rr->cname, rr->ipaddr[ipdx]); } } else if ( strcasecmp(rr->type, "A")==0) { if (tinyfile) { if (ipdx<=0 && rr->cipaddr[0]) fprintf(tinyfile, "%s%s:%s:%s:%s\n", (znix==0 ? "=" : "+"), rr->dnsdomainname, rr->cipaddr, rr->ttl, rr->timestamp); if (ipdx>=0) fprintf(tinyfile, "+%s:%s:%s:%s\n", rr->dnsdomainname, rr->ipaddr[ipdx], rr->ttl, rr->timestamp); } if (namedzone) { if (ipdx<=0 && rr->cipaddr[0]) fprintf(namedzone, "%s.\tIN A\t%s\n", rr->dnsdomainname, rr->cipaddr); if (ipdx>=0) fprintf(namedzone, "%s.\tIN A\t%s\n", rr->dnsdomainname, rr->ipaddr[ipdx]); } } else if (strcasecmp(rr->type, "PTR")==0) { int ip[4] = {0, 0, 0, 0}; char buf[64]; if (ipdx>0) { /* does not make to have more than one IPaddr for a PTR record */ return; } if (ipdx==0 && sscanf(rr->ipaddr[0], "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) { /* lazy user, used DNSipaddr for reverse lookup */ sprintf(buf, "%d.%d.%d.%d.in-addr.arpa", ip[3], ip[2], ip[1], ip[0]); } else { strcpy(buf, rr->dnsdomainname); } if (tinyfile) fprintf(tinyfile, "^%s:%s:%s:%s\n", buf, rr->cname, rr->ttl, rr->timestamp); if (namedzone) fprintf(namedzone, "%s.\tIN PTR\t%s.\n", buf, rr->cname); } else if (strcasecmp(rr->type, "CNAME")==0) { if (tinyfile) fprintf(tinyfile, "C%s:%s:%s:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp); if (namedzone) fprintf(namedzone, "%s.\tIN CNAME\t%s.\n", rr->dnsdomainname, rr->cname); } else if (strcasecmp(rr->type, "TXT")==0) { if (tinyfile) fprintf(tinyfile, "'%s:%s:%s:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp); if (namedzone) fprintf(namedzone, "%s.\tIN TXT\t%s.\n", rr->dnsdomainname, rr->cname); } } #if defined DRAFT_RFC static void parse_rr(struct resourcerecord* rr) { char word1[64]; char word2[64]; int ip[4]; sscanf(rr->rr, "%16s %16s %64s %64s", rr->class, rr->type, word1, word2); if (strcasecmp(rr->type, "NS")==0) { if (sscanf(word1, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) { sprintf(rr->ipaddr[0], "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); } else { int len = strlen(word1); expand_domainname(rr->cname, word1, len); } } else if (strcasecmp(rr->type, "MX")==0) { if (sscanf(word1, "%s", rr->preference)!=1) rr->preference[0] = '\0'; if (sscanf(word2, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) { sprintf(rr->ipaddr[0], "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); } else { int len = strlen(word2); expand_domainname(rr->cname, word2, len); } } else if (strcasecmp(rr->type, "A")==0) { if (sscanf(word1, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) sprintf(rr->ipaddr[0], "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); else rr->ipaddr[0][0] = '\0'; } else if (strcasecmp(rr->type, "PTR")==0) { expand_reverse(rr->dnsdomainname, word1); } else if (strcasecmp(rr->type, "CNAME")==0) { int len = strlen(word1); expand_reverse(rr->cname, word1); } else if (strcasecmp(rr->type, "TXT")==0) { strncpy(rr->cname, word1, 64); } } #endif static void read_resourcerecords(char* dn, int znix) { LDAPMessage* res = NULL; LDAPMessage* m; int ldaperr; if ( (ldaperr = ldap_search_s(ldap_con, dn, LDAP_SCOPE_SUBTREE, "objectclass=DNSrrset", NULL, 0, &res))!=LDAP_SUCCESS ) die_ldap(ldaperr); for (m = ldap_first_entry(ldap_con, res); m; m = ldap_next_entry(ldap_con, m)) { BerElement* ber = NULL; char* attr; char* dn = ldap_get_dn(ldap_con, m); struct resourcerecord rr; int ipaddresses = 0; if (options.ldifname[0]) fprintf(ldifout, "dn: %s\n", dn); rr.cn[0] = '\0'; strncpy(rr.dnsdomainname, zone.domainname, 64); strncpy(rr.class, "IN", 3); rr.type[0] = '\0'; rr.cname[0] = '\0'; rr.cipaddr[0] = '\0'; rr.ttl[0] = '\0'; rr.timestamp[0] = '\0'; rr.preference[0] = '\0'; #if defined DRAFT_RFC rr.aliasedobjectname[0] = '\0'; rr.rr[0] = '\0'; #endif for (attr = ldap_first_attribute(ldap_con, m, &ber); attr; attr = ldap_next_attribute(ldap_con, m, ber)) { int len = strlen(attr); struct berval** bvals; char* dnsnname = ""; if ( (bvals = ldap_get_values_len(ldap_con, m, attr))!=NULL ) { if (bvals[0] && bvals[0]->bv_len>0) { if (strcasecmp(attr, "objectclass")==0) { if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, bvals[0]->bv_val); } else if (strcasecmp(attr, "cn")==0) { strncpy(rr.cn, bvals[0]->bv_val, 64); if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, rr.cn); } else if (strcasecmp(attr, "DNSdomainname")==0) { if (!expand_domainname(rr.dnsdomainname, bvals[0]->bv_val, bvals[0]->bv_len)) rr.dnsdomainname[0] = '\0';; if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, bvals[0]->bv_val); } else if (strcasecmp(attr, "DNSclass")==0) { if (sscanf(bvals[0]->bv_val, "%16s", rr.class)!=1) rr.class[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, rr.class); } else if (strcasecmp(attr, "DNStype")==0) { if (sscanf(bvals[0]->bv_val, "%16s", rr.type)!=1) rr.type[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, rr.type); } else if (strcasecmp(attr, "DNSipaddr")==0) { int ip[4]; for (ipaddresses = 0; bvals[ipaddresses] && ipaddresses<256; ipaddresses++) { rr.ipaddr[ipaddresses][0] = '\0'; if (sscanf(bvals[ipaddresses]->bv_val, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) { sprintf(rr.ipaddr[ipaddresses], "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, rr.ipaddr[ipaddresses]); } } } else if (strcasecmp(attr, "DNScipaddr")==0) { int ip[4]; if (sscanf(bvals[0]->bv_val, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) { sprintf(rr.cipaddr, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, rr.cipaddr); } } else if (strcasecmp(attr, "DNScname")==0) { if (!expand_domainname(rr.cname, bvals[0]->bv_val, bvals[0]->bv_len)) rr.cname[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, bvals[0]->bv_val); } else if (strcasecmp(attr, "DNSttl")==0) { if (sscanf(bvals[0]->bv_val, "%12s", rr.ttl)!=1) rr.ttl[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, rr.ttl); } else if (strcasecmp(attr, "DNStimestamp")==0) { if (sscanf(bvals[0]->bv_val, "%16s", &rr.timestamp)!=1) rr.timestamp[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, rr.timestamp); } else if (strcasecmp(attr, "DNSpreference")==0) { if (sscanf(bvals[0]->bv_val, "%s", rr.preference)!=1) rr.preference[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, bvals[0]->bv_val); } #if defined DRAFT_RFC else if (strcasecmp(attr, "DNSrr")==0) { strncpy(rr.rr, bvals[0]->bv_val, 1024); if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, rr.rr); } else if (strcasecmp(attr, "DNSaliasedobjectname")==0) { if (sscanf(bvals[0]->bv_val, "%256s", rr.aliasedobjectname)!=1) rr.aliasedobjectname[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, rr.aliasedobjectname); } else if (strcasecmp(attr, "DNSmacaddress")==0) { } #endif } ldap_value_free_len(bvals); } } #if defined DRAFT_RFC if (rr.rr[0]) { parse_rr(&rr); } #endif do { ipaddresses--; write_rr(&rr, ipaddresses, znix); } while (ipaddresses>0); #if defined DRAFT_RFC if (rr.aliasedobjectname[0]) read_resourcerecords(rr.aliasedobjectname); #endif if (options.ldifname[0]) fprintf(ldifout, "\n"); if (options.verbose&2) printf("\trr: %s %s %s\n", rr.class, rr.type, rr.dnsdomainname); free(dn); } ldap_msgfree(res); } static void write_zone(void) { int len; char soa[20]; if (tinyfile) { fprintf(tinyfile, "Z%s:%s:%s:%s:%s:%s:%s:%s:%s:%s\n", zone.domainname, zone.zonemaster, zone.adminmailbox, zone.serial, zone.refresh, zone.retry, zone.expire, zone.minimum, zone.ttl, zone.timestamp); } if (namedmaster) { fprintf(namedmaster, "zone \"%s\" %s {\n\ttype master;\n\tfile \"%s.db\";\n};\n", zone.domainname, zone.class, zone.domainname); } if (namedzone) { fprintf(namedzone, "; Automatically generated by ldap2dns - DO NOT EDIT!\n"); if (zone.ttl[0]) fprintf(namedzone, "$TTL %s\n", zone.ttl); else fprintf(namedzone, "$TTL 3600\n"); fprintf(namedzone, "%s. IN SOA ", zone.domainname); len = strlen(zone.zonemaster); fprintf(namedzone, (zone.zonemaster[len-1]=='.') ? "%s " : "%s. ", zone.zonemaster); len = strlen(zone.adminmailbox); fprintf(namedzone, (zone.adminmailbox[len-1]=='.') ? "%s " : "%s. ", zone.adminmailbox); fprintf(namedzone, "(\n\t%s\t; Serial\n\t%s\t; Refresh\n\t%s\t; Retry\n\t%s\t; Expire\n\t%s )\t; Minimum\n", zone.serial, zone.refresh, zone.retry, zone.expire, zone.minimum); } if (options.ldifname[0]) fprintf(ldifout, "\n"); } static void calc_checksum(int* num, int* sum) { LDAPMessage* res = NULL; LDAPMessage* m; int ldaperr; char* attr_list[2] = { "DNSserial", NULL }; *num = *sum = 0; if ( ldaperr = ldap_search_s(ldap_con, options.searchbase[0] ? options.searchbase : NULL, LDAP_SCOPE_SUBTREE, "objectclass=DNSzone", attr_list, 0, &res)!=LDAP_SUCCESS ) die_ldap(ldaperr); for (m = ldap_first_entry(ldap_con, res); m; m = ldap_next_entry(ldap_con, m)) { BerElement* ber = NULL; char* attr = ldap_first_attribute(ldap_con, m, &ber); if (attr) { struct berval** bvals = ldap_get_values_len(ldap_con, m, attr); if (bvals!=NULL) { unsigned tmp; if (sscanf(bvals[0]->bv_val, "%u", &tmp)==1) { (*num)++; *sum += tmp; } ldap_value_free_len(bvals); } } ber_free(ber, 0); } ldap_msgfree(res); } static void read_dnszones(void) { LDAPMessage* res = NULL; LDAPMessage* m; int ldaperr; if (tinyfile) fprintf(tinyfile, "# Automatically generated by ldap2dns - DO NOT EDIT!\n"); if (namedmaster) fprintf(namedmaster, "; Automatically generated by ldap2dns - DO NOT EDIT!\n"); if ( (ldaperr = ldap_search_s(ldap_con, options.searchbase[0] ? options.searchbase : NULL, LDAP_SCOPE_SUBTREE, "objectclass=DNSzone", NULL, 0, &res))!=LDAP_SUCCESS ) die_ldap(ldaperr); for (m = ldap_first_entry(ldap_con, res); m; m = ldap_next_entry(ldap_con, m)) { BerElement* ber = NULL; char* attr; char* dn; int i, zonenames = 0; char zdn[256][64]; char ldif0; strncpy(zone.class, "IN", 3); zone.serial[0] = '\0'; zone.refresh[0] = '\0'; zone.retry[0] = '\0'; zone.expire[0] = '\0'; zone.minimum[0] = '\0'; zone.ttl[0] = '\0'; zone.timestamp[0] = '\0'; dn = ldap_get_dn(ldap_con, m); if (options.ldifname[0]) fprintf(ldifout, "dn: %s\n", dn); for (attr = ldap_first_attribute(ldap_con, m, &ber); attr; attr = ldap_next_attribute(ldap_con, m, ber)) { struct berval** bvals = ldap_get_values_len(ldap_con, m, attr); if (bvals!=NULL) { if (bvals[0] && bvals[0]->bv_len>0) { if (strcasecmp(attr, "objectclass")==0 || strcasecmp(attr, "DNSclass")==0 || strcasecmp(attr, "DNStype")==0 || strcasecmp(attr, "cn")==0) { if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, bvals[0]->bv_val); } else if (strcasecmp(attr, "DNSzonename")==0) { for (zonenames = 0; bvals[zonenames] && zonenames<256; zonenames++) { if (sscanf(bvals[zonenames]->bv_val, "%64s", &zdn[zonenames])!=1) zdn[zonenames][0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zdn[zonenames]); } } else if (strcasecmp(attr, "DNSserial")==0) { if (sscanf(bvals[0]->bv_val, "%12s", zone.serial)!=1) zone.serial[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zone.serial); } else if (strcasecmp(attr, "DNSrefresh")==0) { if (sscanf(bvals[0]->bv_val, "%12s", zone.refresh)!=1) zone.refresh[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zone.refresh); } else if (strcasecmp(attr, "DNSretry")==0) { if (sscanf(bvals[0]->bv_val, "%12s", zone.retry)!=1) zone.retry[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zone.retry); } else if (strcasecmp(attr, "DNSexpire")==0) { if (sscanf(bvals[0]->bv_val, "%12s", zone.expire)!=1) zone.expire[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zone.expire); } else if (strcasecmp(attr, "DNSminimum")==0) { if (sscanf(bvals[0]->bv_val, "%12s", zone.minimum)!=1) zone.minimum[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zone.minimum); } else if (strcasecmp(attr, "DNSadminmailbox")==0) { if (sscanf(bvals[0]->bv_val, "%64s", zone.adminmailbox)!=1) zone.adminmailbox[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zone.adminmailbox); } else if (strcasecmp(attr, "DNSzonemaster")==0) { if (sscanf(bvals[0]->bv_val, "%64s", zone.zonemaster)!=1) zone.zonemaster[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zone.zonemaster); } else if (strcasecmp(attr, "DNSttl")==0) { if (sscanf(bvals[0]->bv_val, "%12s", zone.ttl)!=1) zone.ttl[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zone.ttl); } else if (strcasecmp(attr, "DNStimestamp")==0) { if (sscanf(bvals[0]->bv_val, "%16s", zone.timestamp)!=1) zone.timestamp[0] = '\0'; else if (options.ldifname[0]) fprintf(ldifout, "%s: %s\n", attr, zone.timestamp); } } ldap_value_free_len(bvals); } } ldif0 = options.ldifname[0]; for (i = 0; i0) options.ldifname[0] = '\0'; if (options.verbose&1) printf("zonename: %s\n", zone.domainname); if (options.output&OUTPUT_DB) { char namedzonename[128]; sprintf(namedzonename, "%s.db", zone.domainname); if ( !(namedzone = fopen(namedzonename, "w")) ) die_exit("Unable to open db-file for writing"); } write_zone(); read_resourcerecords(dn, i); if (namedzone) fclose(namedzone); if (options.verbose&2) printf("\n"); if (options.ldifname[0]) fprintf(ldifout, "\n"); } options.ldifname[0] = ldif0; free(dn); } ldap_msgfree(res); } static int connect() { int i; for (i = 0; i ldap2tinydns/run #!/bin/sh exec 2>&1 exec envdir ./env softlimit -d250000 /usr/bin/ldap2dns -e "cd /var/tinydns/root && /usr/bin/tinydns-data" EOF_run chmod +t ldap2tinydns chmod 755 ldap2tinydns/run echo "/var/tinydns/root" > ldap2tinydns/env/TINYDNSDIR echo "60" > ldap2tinydns/env/LDAP2DNS_UPDATE echo "data" > ldap2tinydns/env/LDAP2DNS_OUTPUT cat << EOF_logrun > ldap2tinydns/log/run #!/bin/sh exec setuidgid nobody multilog t ./main EOF_logrun chown nobody.nobody ldap2tinydns/log/main chmod g+s ldap2tinydns/log/main chmod 755 ldap2tinydns/log/run chown nobody.nobody ldap2tinydns/log/status echo "To supervise ldap2dns do a symbolic link from /service onto ldap2dns" ldap2dns-0.3.1/CHANGELOG0100664000100100010010000000441207526205701013376 0ustar jriefjriefVersion 0.3.1 (latest) + ldap2dns now can work together with tinydns. This means that all DNS queries are passed data file is generated, but all Make ldap2dns behave like a secondary nameserver by storing the serial number, expire, refresh, retry and minimum values in a record. Version 0.3.0 + A new interface for web-administration written compleatly in PHP. Much easier to install that the old mod_perl interface. Version 0.2.6 + Password passed with option -w now is invisible to 'ps'. + ldap2tinydns-conf now takes a parameter to specify to user under which ldap2dns will be running. Version 0.2.5 - Tested with OpenLDAP-2.0. - Adopted dns.schema with official numbers. Version 0.2.4 - Check for next availabe server in /etc/ldap.conf if one is unavialable. - Schema for DNSzone in dns.schema was corrected. Version 0.2.3 - Replaced integer variables for DNSserial, DNSttl etc. by strings to allow better default handling by tinydns-data. - ldap2dns now writes logfiles. Version 0.2.2 - Tested with djbdns-1.05 - Removed compleatly the possibility to create a binary data.cdb file. Reasons: * It just takes a few milliseconds to create a data.cdb file with tinydns-data. * Its much safer to have an ASCII data file handy just in case something goes wrong. * I am too lazy to adopt ldap2dns for each new version of djbdns. * ldap2dns does not have to be linked statically against any other package. - Now the output option takes parameters data and/or db instead of numbers. Version 0.2.1 - Additional attribute in DNSrrset: DNScipaddr Canonical IP address, which when used instead of DNSipaddr automatically resolves reverse. - Using Environement Variables LDAP2DNS_UPDATE and LDAP2DNS_OUTPUT for default values used by ldap2dns. - If started as daemon, does not exit if connection to LDAP server fails but tries to reconnect after a timeout. - An external program can be called if ldap2dns detects a modification in the database. Version 0.2.0 - New schema, unfortunately not compatible with old one, but now its unambigous. - Mapping for reverse lookup works fine. - ldap2dns now can be started by daemontools. - Fixed a bug for DNSrrset's with type=TXT - Much better naming scheme for dn's when using import.pl - RPM support ldap2dns-0.3.1/askldap.c0100664000100100010010000005446407525762465014001 0ustar jriefjrief/* Patch for tinydns to pass DNS-query to LDAP in favour of a cdb lookup. * $Id: askldap.c,v 1.8 2002/08/12 16:41:25 jrief Exp $ * Copyright 2002 */ #include #include #include #include #include #include #include #include #include #include #include #include "alloc.h" #include "byte.h" #include "response.h" #include "askldap.h" #include "dns.h" static LDAP* ldap_con; static sigjmp_buf stack_context; static struct { char ldaphosts[256]; const char* basedn; char binddn[256]; char bindpwd[16]; struct timeval timeout; int verbose; int initialized; } options; struct zonerecord { char zonedn[256]; char zonename[64]; char class[16]; char type[16]; char adminmailbox[64]; char zonemaster[64]; unsigned long serial, refresh, retry, expire, minimum; int ttl; int timestamp; }; struct resourcerecord { char qualifieddomainname[256]; char class[16]; char type[16]; char ipaddr[8][4]; int numipaddrs; char cname[256]; unsigned int preference; int ttl; int timestamp; int additionalinfo; struct resourcerecord* next; }; enum { ASKLDAP_RETRY = 1, ASKLDAP_RETURN = 2, ASKLDAP_RECONNECT = 3 }; static void assert_ldap(int err) { static int retries; switch (err) { case LDAP_SUCCESS: return; case LDAP_TIMELIMIT_EXCEEDED: fprintf(stderr, "Warning: %s\n", ldap_err2string(err)); retries++; if (retries<3) siglongjmp(stack_context, ASKLDAP_RETRY); retries = 0; siglongjmp(stack_context, ASKLDAP_RETURN); case LDAP_TIMEOUT: case LDAP_NO_SUCH_OBJECT: fprintf(stderr, "Warning: %s\n", ldap_err2string(err)); siglongjmp(stack_context, ASKLDAP_RETURN); case LDAP_BUSY: case LDAP_UNAVAILABLE: case LDAP_UNWILLING_TO_PERFORM: case LDAP_SERVER_DOWN: fprintf(stderr, "Warning: %s\n", ldap_err2string(err)); siglongjmp(stack_context, ASKLDAP_RECONNECT); default: fprintf(stderr, "Fatal error: %s\n", ldap_err2string(err)); #ifdef _DEBUG abort(); #else exit(1); #endif } } void free_domainrecords(struct resourcerecord* anchor) { struct resourcerecord* ptr; for (ptr = anchor; ptr; ptr = anchor) { anchor = anchor->next; alloc_free(ptr); } } static void fill_resourcerecord(struct resourcerecord* rr, LDAPMessage* m, const char* zonename) { BerElement* ber = NULL; char* attr; byte_zero(rr, sizeof(struct resourcerecord)); strcpy(rr->class, "IN"); for (attr = ldap_first_attribute(ldap_con, m, &ber); attr; attr = ldap_next_attribute(ldap_con, m, ber)) { struct berval** bvals = ldap_get_values_len(ldap_con, m, attr); if (bvals && bvals[0] && bvals[0]->bv_len>0) { if (strcasecmp(attr, "dnsdomainname")==0) { char tmp[64]; if (sscanf(bvals[0]->bv_val, "%64s", tmp)==1) { if (zonename[0]!='\0') snprintf(rr->qualifieddomainname, 256, "%s.%s", tmp, zonename); else strncpy(rr->qualifieddomainname, tmp, 256); } } else if (strcasecmp(attr, "dnstype")==0) { if (sscanf(bvals[0]->bv_val, "%16s", rr->type)!=1) { rr->type[0] = '\0'; } } else if (strcasecmp(attr, "dnsipaddr")==0) { int k, ip[4]; for (k = 0; bvals[k] && k < 8-rr->numipaddrs; k++) { if (sscanf(bvals[k]->bv_val, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) { rr->ipaddr[rr->numipaddrs][0] = (char)ip[0]; rr->ipaddr[rr->numipaddrs][1] = (char)ip[1]; rr->ipaddr[rr->numipaddrs][2] = (char)ip[2]; rr->ipaddr[rr->numipaddrs][3] = (char)ip[3]; rr->numipaddrs++; } } } else if (rr->numipaddrs<8 && strcasecmp(attr, "dnscipaddr")==0) { int ip[4]; if (sscanf(bvals[0]->bv_val, "%d.%d.%d.%d", &ip[0], &ip[1], &ip[2], &ip[3])==4) { rr->ipaddr[rr->numipaddrs][0] = (char)ip[0]; rr->ipaddr[rr->numipaddrs][1] = (char)ip[1]; rr->ipaddr[rr->numipaddrs][2] = (char)ip[2]; rr->ipaddr[rr->numipaddrs][3] = (char)ip[3]; rr->numipaddrs++; } } else if (strcasecmp(attr, "dnscname")==0) { if (sscanf(bvals[0]->bv_val, "%256s", rr->cname)==1) { int len = strlen(rr->cname); if (rr->cname[len-1]!='.' && zonename[0]!='\0') { strcat(rr->cname, "."); strncat(rr->cname, zonename, 252-len); strcat(rr->cname, "."); } } else { rr->cname[0] = '\0'; } } else if (strcasecmp(attr, "dnsttl")==0) { if (sscanf(bvals[0]->bv_val, "%d", &rr->ttl)!=1) rr->ttl = 0; } else if (strcasecmp(attr, "dnstimestamp")==0) { if (sscanf(bvals[0]->bv_val, "%d", &rr->timestamp)!=1) rr->timestamp = 0; } else if (strcasecmp(attr, "dnspreference")==0) { if (sscanf(bvals[0]->bv_val, "%u", &rr->preference)!=1) rr->preference = 1; } } ldap_value_free_len(bvals); } if (rr->qualifieddomainname[0]=='\0') strncpy(rr->qualifieddomainname, zonename, 256); } static void fill_zonerecord(struct zonerecord* zone, LDAPMessage* m) { BerElement* ber = NULL; char* attr; byte_zero(zone, sizeof(struct zonerecord)); strcpy(zone->class, "IN"); for (attr = ldap_first_attribute(ldap_con, m, &ber); attr; attr = ldap_next_attribute(ldap_con, m, ber)) { struct berval** bvals = ldap_get_values_len(ldap_con, m, attr); if (bvals && bvals[0] && bvals[0]->bv_len>0) { if (strcasecmp(attr, "dnstype")==0) { if (sscanf(bvals[0]->bv_val, "%16s", zone->type)!=1) zone->type[0] = '\0'; } else if (strcasecmp(attr, "dnsserial")==0) { if (sscanf(bvals[0]->bv_val, "%lu", &zone->serial)!=1) zone->serial = 0; } else if (strcasecmp(attr, "dnsrefresh")==0) { if (sscanf(bvals[0]->bv_val, "%lu", &zone->refresh)!=1) zone->refresh = 0; } else if (strcasecmp(attr, "dnsretry")==0) { if (sscanf(bvals[0]->bv_val, "%lu", &zone->retry)!=1) zone->retry = 0; } else if (strcasecmp(attr, "dnsexpire")==0) { if (sscanf(bvals[0]->bv_val, "%lu", &zone->expire)!=1) zone->expire = 0; } else if (strcasecmp(attr, "dnsminimum")==0) { if (sscanf(bvals[0]->bv_val, "%lu", &zone->minimum)!=1) zone->minimum = 0; } else if (strcasecmp(attr, "dnsadminmailbox")==0) { if (sscanf(bvals[0]->bv_val, "%64s", zone->adminmailbox)!=1) zone->adminmailbox[0] = '\0'; } else if (strcasecmp(attr, "dnszonemaster")==0) { if (sscanf(bvals[0]->bv_val, "%64s", zone->zonemaster)!=1) zone->zonemaster[0] = '\0'; } else if (strcasecmp(attr, "dnsttl")==0) { if (sscanf(bvals[0]->bv_val, "%d", &zone->ttl)!=1) zone->ttl = 0; } else if (strcasecmp(attr, "dnstimestamp")==0) { if (sscanf(bvals[0]->bv_val, "%d", &zone->timestamp)!=1) zone->timestamp = 0; } else if (strcasecmp(attr, "dnszonename")==0) { if (sscanf(bvals[0]->bv_val, "%s", zone->zonename)!=1) zone->zonename[0] = '\0'; } } ldap_value_free_len(bvals); } } static int find_ipaddr(const char* queryname, char ip[4]) { static char *rrattrs[] = { "dnsipaddr", "dnscipaddr", 0 }; LDAPMessage* res = NULL; LDAPMessage* m; int ret = 0; char filter[256], domainname[64]; const char *zonename = queryname; domainname[0] = '\0'; while (*zonename) { int len = snprintf(filter, 256, "(&(dnszonename=%s", zonename); if (filter[len-1]=='.') filter[len-1] = '\0'; strncat(filter, ")(objectclass=dnszone)(dnsclass=IN))", 256-len); assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); if (m = ldap_first_entry(ldap_con, res)) { char* zonedn = ldap_get_dn(ldap_con, m); if (ldap_next_entry(ldap_con, m)) printf("Warning: ambigous zonename for %s in %s\n", zonename, zonedn); if (domainname[0]!='\0') { len = strlen(domainname); if (domainname[len-1]=='.') domainname[len-1] = '\0'; snprintf(filter, 256, "(&(|(dnsdomainname=%s)(dnscname=%s))(objectclass=dnsrrset)(dnsclass=IN)(|(dnsipaddr=*)(dnscipaddr=*)))", domainname, domainname); } else { strcpy(filter, "(&(!(dnsdomainname=*))(objectclass=dnsrrset)(dnsclass=IN)(|(dnsipaddr=*)(dnscipaddr=*)))"); } ldap_msgfree(res); assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); if (m = ldap_first_entry(ldap_con, res)) { struct resourcerecord rr; fill_resourcerecord(&rr, m, ""); if (rr.numipaddrs>0) { rr.numipaddrs = rand()%rr.numipaddrs; ip[0] = rr.ipaddr[rr.numipaddrs][0]; ip[1] = rr.ipaddr[rr.numipaddrs][1]; ip[2] = rr.ipaddr[rr.numipaddrs][2]; ip[3] = rr.ipaddr[rr.numipaddrs][3]; ret = 1; } } ldap_memfree(zonedn); ldap_msgfree(res); res = NULL; if (ret) return 1; break; } while (*zonename && *zonename!='.') { domainname[zonename-queryname] = *zonename; zonename++; } domainname[zonename-queryname] = *zonename; if (*zonename=='.') { zonename++; domainname[zonename-queryname] = '\0'; } } /* sometimes the queryname resolves directly as cname in some other records */ snprintf(filter, 256, "(&(dnscname=%s)(objectclass=dnsrrset)(dnsclass=IN)(|(dnsipaddr=*)(dnscipaddr=*)))", queryname); assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); if (m = ldap_first_entry(ldap_con, res)) { struct resourcerecord rr; fill_resourcerecord(&rr, m, ""); if (rr.numipaddrs>0) { rr.numipaddrs = rand()%rr.numipaddrs; ip[0] = rr.ipaddr[rr.numipaddrs][0]; ip[1] = rr.ipaddr[rr.numipaddrs][1]; ip[2] = rr.ipaddr[rr.numipaddrs][2]; ip[3] = rr.ipaddr[rr.numipaddrs][3]; ret = 1; } } ldap_msgfree(res); return ret; } static struct resourcerecord* find_reverserecord(const char* queryname, int ip[4]) { static char *rrattrs[] = { "dnstype", "dnsdomainname", "dnscname", "dnsttl", 0 }; LDAPMessage* res = NULL; struct resourcerecord* rr = NULL; LDAPMessage* m; char filter[256]; snprintf(filter, 256, "(&(dnscipaddr=%u.%u.%u.%u)(objectclass=dnsrrset)(dnsclass=IN))", ip[0], ip[1], ip[2], ip[3]); assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); if (m = ldap_first_entry(ldap_con, res)) { char* rrsetdn = ldap_get_dn(ldap_con, m); char** explodedn = NULL; rr = (void*)alloc(sizeof(struct resourcerecord)); fill_resourcerecord(rr, m, ""); if (ldap_next_entry(ldap_con, m)) printf("Warning: ambigous IP-address for %u.%u.%u.%u in dn: %s\n", ip[0], ip[1], ip[2], ip[3], rrsetdn); explodedn = ldap_explode_dn(rrsetdn, 0); if (explodedn[0]) { static char *zoneattrs[] = { "dnszonename", 0 }; char zonedn[256]; int i, len = 0; struct zonerecord zone; zonedn[0] = '\0'; for (i = 1; explodedn[i]; i++) len += snprintf(zonedn+len, 256-len, "%s,", explodedn[i]); zonedn[len-1] = '\0'; ldap_msgfree(res); assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, "(objectclass=dnszone)", zoneattrs, 0, &options.timeout, &res)); m = ldap_first_entry(ldap_con, res); if (m==NULL) printf("Error: parent dn: %s not found for %s\n", zonedn, rrsetdn); fill_zonerecord(&zone, m); len = strlen(rr->qualifieddomainname); if (len==0) { len = strlen(rr->cname); if (rr->cname[len-1]!='.') { strcat(rr->cname, "."); strncat(rr->cname, zone.zonename, 252-len); } } else { /* in those situations where a dnsrrset * defines something like MX or NS for a zone * and also sets a canonical name for the * service. */ snprintf(rr->cname, 256, "%s.%s", rr->qualifieddomainname, zone.zonename); } strcpy(rr->type, "PTR"); strncpy(rr->qualifieddomainname, queryname, 256); } ldap_memfree(rrsetdn); ldap_value_free(explodedn); } ldap_msgfree(res); return rr; } static struct resourcerecord* read_domainrecords(const char* zonedn, const char* domainname, const char* zonename) { static char *rrattrs[] = { "dnsdomainname", "dnstype", "dnsttl", "dnscname", "dnsipaddr", "dnscipaddr", "dnstimestamp", "dnspreference", 0 }; LDAPMessage* res = NULL; LDAPMessage* m; char filter[256]; struct resourcerecord *prev, *anchor = NULL; if (domainname[0]) { if (strstr(zonename, "in-addr.arpa")) { unsigned int ip[4]; char queryname[256]; snprintf(queryname, 256, "%s.%s", domainname, zonename); if (sscanf(queryname, "%3u.%3u.%3u.%3u", &ip[3], &ip[2], &ip[1], &ip[0])!=4) return NULL; snprintf(filter, 256, "(&(dnsipaddr=%u.%u.%u.%u)(objectclass=dnsrrset)(dnsclass=IN))", ip[0], ip[1], ip[2], ip[3]); assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); if (m = ldap_first_entry(ldap_con, res)) { struct resourcerecord* rr; rr = (void*)alloc(sizeof(struct resourcerecord)); fill_resourcerecord(rr, m, zonename); strncpy(rr->qualifieddomainname, queryname, 256); ldap_msgfree(res); return rr; } else { /* ipaddr not in our baliwick, search the whole tree for canonical ipaddr */ ldap_msgfree(res); return find_reverserecord(queryname, ip); } } else { snprintf(filter, 256, "(&(dnsdomainname=%s)(objectclass=dnsrrset)(dnsclass=IN))", domainname); assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); } } else { snprintf(filter, 256, "(&(!(dnsdomainname=*))(objectclass=dnsrrset)(dnsclass=IN))"); assert_ldap(ldap_search_st(ldap_con, zonedn, LDAP_SCOPE_SUBTREE, filter, rrattrs, 0, &options.timeout, &res)); } for (m = ldap_first_entry(ldap_con, res); m; m = ldap_next_entry(ldap_con, m)) { struct resourcerecord* rr; rr = (void*)alloc(sizeof(struct resourcerecord)); fill_resourcerecord(rr, m, zonename); if (anchor==NULL) { prev = anchor = rr; } else { prev->next = rr; prev = rr; } if (options.verbose&1) printf("\trr: %s %s\n", domainname, rr->type); } ldap_msgfree(res); return anchor; } static int read_dnszone(struct zonerecord* zone, const char* zonename) { static char *zoneattrs[] = { "dnszonename", "dnstype", "dnsserial", "dnsrefresh", "dnsretry", "dnsexpire", "dnsminimum", "dnszonemaster", "dnsadminmailbox", "dnsttl", "dnstimestamp", 0 }; LDAPMessage* res = NULL; LDAPMessage* m; char* dn; char filter[256]; snprintf(filter, 256, "(&(dnszonename=%s)(objectclass=dnszone)(dnsclass=IN))", zonename); assert_ldap(ldap_search_st(ldap_con, options.basedn, LDAP_SCOPE_SUBTREE, filter, zoneattrs, 0, &options.timeout, &res)); m = ldap_first_entry(ldap_con, res); if (m==NULL) { ldap_msgfree(res); return 0; } dn = ldap_get_dn(ldap_con, m); fill_zonerecord(zone, m); m = ldap_next_entry(ldap_con, m); if (m) { char* otherdn = ldap_get_dn(ldap_con, m); printf("Warning: ambigous zonename found in dn: %s and dn: %s\n", dn, otherdn); ldap_memfree(otherdn); } strncpy(zone->zonedn, dn, 256); ldap_memfree(dn); ldap_msgfree(res); return 1; } static void djb_name(const char* dotname, char* djbname) { const char* c = dotname; int i, k; for (i = 0; *c; c++) { k = i; while (*c!='.') { k++; djbname[k] = *c; if (*c=='\0') { djbname[i] = k-i-1; return; } c++; } djbname[i] = k-i; i = k+1; } djbname[i] = '\0'; } static void djb_type(const char* dottype, char djbtype[2]) { djbtype[0] = '\0'; if (strcasecmp(dottype, "A")==0) djbtype[1] = 001; else if (strcasecmp(dottype, "NS")==0) djbtype[1] = 002; else if (strcasecmp(dottype, "CNAME")==0) djbtype[1] = 005; else if (strcasecmp(dottype, "SOA")==0) djbtype[1] = 006; else if (strcasecmp(dottype, "PTR")==0) djbtype[1] = 014; else if (strcasecmp(dottype, "MX")==0) djbtype[1] = 017; else if (strcasecmp(dottype, "TXT")==0) djbtype[1] = 020; } static void split_djbstyle(const char* djbname, char* domainname, char* zonename, int offset) { int i, k, m = 0, n = 0; for (i = *djbname; i; i = *++djbname) { if (offset>0) { offset--; for (k = m; k0 ? m-1 : 0] = '\0'; zonename[n>0 ? n-1 : 0] = '\0'; } static void build_response_section(struct resourcerecord *rr, char qtype[2], int section) { char djbname[256], djbtype[2]; djb_name(rr->qualifieddomainname, djbname); djb_type(rr->type, djbtype); if (byte_equal(djbtype, 2, DNS_T_A)) { if (byte_equal(qtype, 2, DNS_T_A) || byte_equal(qtype, 2, DNS_T_ANY)) { response_rstart(djbname, djbtype, rr->ttl); response_addbytes(rr->ipaddr[rand()%rr->numipaddrs], 4); response_rfinish(section); } } else if (byte_equal(djbtype, 2, DNS_T_CNAME)) { response_rstart(djbname, djbtype, rr->ttl); djb_name(rr->cname, djbname); response_addname(djbname); response_rfinish(section); } else if (byte_equal(djbtype, 2, DNS_T_NS)) { if (byte_equal(qtype, 2, DNS_T_NS) || byte_equal(qtype, 2, DNS_T_ANY)) { response_rstart(djbname, djbtype, rr->ttl); if (rr->cname[0]) { djb_name(rr->cname, djbname); response_addname(djbname); rr->additionalinfo = 1; } else { response_addbytes(rr->ipaddr[rand()%rr->numipaddrs], 4); } response_rfinish(section); } } else if (byte_equal(djbtype, 2, DNS_T_PTR)) { response_rstart(djbname, djbtype, rr->ttl); djb_name(rr->cname, djbname); response_addname(djbname); response_rfinish(section); } else if (byte_equal(djbtype, 2, DNS_T_MX)) { if (byte_equal(qtype, 2, DNS_T_MX) || byte_equal(qtype, 2, DNS_T_ANY)) { char tmp[2]; response_rstart(djbname, djbtype, rr->ttl); tmp[0] = rr->preference/0x100; tmp[1] = rr->preference%0x100; response_addbytes(tmp, 2); if (rr->cname[0]) { djb_name(rr->cname, djbname); response_addname(djbname); rr->additionalinfo = 1; } else { response_addbytes(rr->ipaddr[rand()%rr->numipaddrs], 4); } response_rfinish(section); } } } static void build_soa_section(struct zonerecord *zone, int section) { time_t now; char defaultsoa[20]; char djbname[256]; char zonesoa[20]; unsigned long tmp; time(&now); djb_name(zone->zonename, djbname); response_rstart(djbname, DNS_T_SOA, zone->ttl); djb_name(zone->zonemaster, djbname); response_addname(djbname); djb_name(zone->adminmailbox, djbname); response_addname(djbname); uint32_pack_big(defaultsoa, now); if (byte_equal(defaultsoa,4,"\0\0\0\0")) defaultsoa[3] = 1; byte_copy(defaultsoa + 4, 16, "\0\0\100\000\0\0\010\000\0\020\000\000\0\0\012\000"); if (zone->serial==0) uint32_unpack_big(defaultsoa, &tmp); else tmp = zone->serial; uint32_pack_big(zonesoa, tmp); if (zone->refresh==0) uint32_unpack_big(defaultsoa+4, &tmp); else tmp = zone->refresh; uint32_pack_big(zonesoa+4, tmp); if (zone->retry==0) uint32_unpack_big(defaultsoa+8, &tmp); else tmp = zone->retry; uint32_pack_big(zonesoa+8, tmp); if (zone->expire==0) uint32_unpack_big(defaultsoa+12, &tmp); else tmp = zone->expire; uint32_pack_big(zonesoa+12, tmp); if (zone->minimum==0) uint32_unpack_big(defaultsoa+16, &tmp); else tmp = zone->minimum; uint32_pack_big(zonesoa+16, tmp); response_addbytes(zonesoa, 20); response_rfinish(section); } static void build_additional_section(struct resourcerecord *rr) { char djbname[256], ip[4]; if (rr->additionalinfo && find_ipaddr(rr->cname, ip)) { djb_name(rr->cname, djbname); response_rstart(djbname, DNS_T_A, rr->ttl); response_addbytes(ip, 4); response_rfinish(RESPONSE_ADDITIONAL); } } static int connect_and_bind() { ldap_con = ldap_init(options.ldaphosts, LDAP_PORT); if (ldap_simple_bind_s(ldap_con, options.binddn, options.bindpwd)==LDAP_SUCCESS) { printf("Connected to %s as \"%s\"\n", options.ldaphosts, options.binddn); return 1; } ldap_con = NULL; return 0; } int askldap_query(const char* djbdomainname, char qtype[2]) { int offset; char domainname[64], zonename[64]; struct zonerecord zoneinfo; int answer_ok = 0, flagsoa = 0, flagns = 0; if (!options.initialized) return 0; switch (sigsetjmp(stack_context, 1)) { default: if (ldap_con==NULL && !connect_and_bind()) return answer_ok; break; case ASKLDAP_RECONNECT: if (connect_and_bind()) break; return answer_ok; case ASKLDAP_RETURN: return answer_ok; } for (offset = 0; offset<32; offset++) { struct resourcerecord *rransw, *rrauth, *rr; split_djbstyle(djbdomainname, domainname, zonename, offset); if (zonename[0]=='\0') return 0; if (!read_dnszone(&zoneinfo, zonename)) continue; rransw = read_domainrecords(zoneinfo.zonedn, domainname, zonename); rrauth = NULL; if (offset==0) { /* query is in our bailiwick */ if (byte_equal(qtype, 2, DNS_T_ANY) || byte_equal(qtype, 2, DNS_T_SOA)) { build_soa_section(&zoneinfo, RESPONSE_ANSWER); flagsoa = 1; } for (rr = rransw; rr; rr = rr->next) { build_response_section(rr, qtype, RESPONSE_ANSWER); answer_ok = 1; } if (!flagsoa) { build_soa_section(&zoneinfo, RESPONSE_AUTHORITY); flagsoa = 1; } if (!byte_equal(qtype, 2, DNS_T_ANY) && !byte_equal(qtype, 2, DNS_T_NS)) { for (rr = rransw; rr; rr = rr->next) if (strcmp(rr->type, "NS")==0) { build_response_section(rr, DNS_T_NS, RESPONSE_AUTHORITY); flagns = 1; } } } else { for (rr = rransw; rr; rr = rr->next) { if (strcmp(rr->type, "NS")==0) { build_response_section(rr, qtype, RESPONSE_AUTHORITY); flagns = 1; } } if (!flagns) { for (rr = rransw; rr; rr = rr->next) { build_response_section(rr, qtype, RESPONSE_ANSWER); answer_ok = 1; } if (answer_ok) { rrauth = read_domainrecords(zoneinfo.zonedn, "", zonename); } else { build_soa_section(&zoneinfo, RESPONSE_AUTHORITY); flagsoa = 1; } } for (rr = rrauth; rr; rr = rr->next) { if (strcmp(rr->type, "NS")==0) { build_response_section(rr, DNS_T_NS, RESPONSE_AUTHORITY); flagns = 1; } } } for (rr = rransw; rr; rr = rr->next) build_additional_section(rr); for (rr = rrauth; rr; rr = rr->next) build_additional_section(rr); free_domainrecords(rransw); free_domainrecords(rrauth); break; } return answer_ok || flagsoa || flagns; } void askldap_init(const char* ldaphost, const char* basedn, const char* binddn, const char* passwd) { strncpy(options.ldaphosts, ldaphost, 256); options.basedn = basedn; if (binddn) strncpy(options.binddn, binddn, 256); if (passwd) strncpy(options.bindpwd, passwd, 16); /* LDAP timeout is hardcoded to 2/10 second. * This must be enough because bindoperations usually * timeout after one second and here we usually have to * send five queries to the LDAP-server */ options.timeout.tv_sec = 1; options.timeout.tv_usec = 200000; options.verbose = 0; options.initialized = 1; connect_and_bind(); } ldap2dns-0.3.1/askldap.h0100664000100100010010000000054707525762465013777 0ustar jriefjrief/* Patch for tinydns to pass DNS-query to LDAP in favour of a cdb lookup. * $Id: askldap.h,v 1.8 2002/08/12 16:41:25 jrief Exp $ * Copyright 2002 */ extern int askldap_query(const char* djbdomainname, char qtype[2]); extern void askldap_init(const char* ldaphost, const char* basedn, const char* binddn, const char* passwd);