mirror of
https://github.com/bklang/ldap2dns.git
synced 2025-10-26 14:04:14 -04:00
Importing version 0.2.2
git-svn-id: https://svn.alkaloid.net/gpl/ldap2dns/trunk@2 06cd67b6-e706-0410-b29e-9de616bca6e9
This commit is contained in:
49
CHANGELOG
Normal file
49
CHANGELOG
Normal file
@@ -0,0 +1,49 @@
|
||||
Version 0.2.3
|
||||
+ Check for next availabe server in /etc/ldap.conf
|
||||
if first one is unavialable.
|
||||
|
||||
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
|
||||
|
||||
18
Makefile
18
Makefile
@@ -1,18 +1,12 @@
|
||||
# ldap2dns Makefile
|
||||
VERSION=0.2.0
|
||||
RELEASE=1
|
||||
WITHTINYDNS=-DWITH_TINYDNS
|
||||
# $Id: Makefile,v 1.22 2001/02/16 09:51:23 jrief Exp $
|
||||
VERSION=0.2.2
|
||||
RELEASE=2
|
||||
CC=gcc -O2
|
||||
DJBDNSDIR=../djbdns-1.02
|
||||
INC=-I$(DJBDNSDIR)
|
||||
CFLAGS=$(INC) $(WITHTINYDNS) -DVERSION='"$(VERSION)"'
|
||||
OBJS=ldap2dns.o
|
||||
LIBS=-lldap -llber -lresolv
|
||||
LD=gcc
|
||||
LDFLAGS=
|
||||
ALIBS=$(DJBDNSDIR)/dns.a $(DJBDNSDIR)/env.a $(DJBDNSDIR)/libtai.a \
|
||||
$(DJBDNSDIR)/cdb.a $(DJBDNSDIR)/alloc.a $(DJBDNSDIR)/buffer.a \
|
||||
$(DJBDNSDIR)/unix.a $(DJBDNSDIR)/byte.a
|
||||
INSTALL_PREFIX=
|
||||
PREFIXDIR=$(INSTALL_PREFIX)/usr
|
||||
LDAPCONFDIR=$(INSTALL_PREFIX)/etc/openldap
|
||||
@@ -21,8 +15,8 @@ SPECFILE=ldap2dns.spec
|
||||
|
||||
all: ldap2dns
|
||||
|
||||
ldap2dns: $(OBJS) $(LIBS) $(ALIBS)
|
||||
$(LD) $(LDFLAGS) -o $@ $(OBJS) $(ALIBS) $(LIBS)
|
||||
ldap2dns: $(OBJS) $(LIBS)
|
||||
$(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
ln -f ldap2dns ldap2dnsd
|
||||
|
||||
ldap2dns.o: ldap2dns.c
|
||||
@@ -38,7 +32,7 @@ install: all
|
||||
install -o root -g root -m 644 dns.oc.conf $(LDAPCONFDIR)/
|
||||
|
||||
clean:
|
||||
rm -f $(OBJS) ldap2dns ldap2dnsd data* $(SPECFILE)
|
||||
rm -f $(OBJS) ldap2dns ldap2dnsd data* *.db $(SPECFILE)
|
||||
|
||||
tar: clean
|
||||
cd ..; \
|
||||
|
||||
185
README.html
185
README.html
@@ -1,16 +1,17 @@
|
||||
<H1 align=center>LDAP to DNS gateway</H1>
|
||||
<P>
|
||||
<B>ldap2dns</B> is a program to create DNS records directly from a LDAP directory.
|
||||
It can and should be be used to replace the secondary name-server by a second
|
||||
primary one.<BR>
|
||||
<B>ldap2dns</B> helps to reduce all kind of administration overhead.
|
||||
<B>ldap2dns</B> 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.<BR>
|
||||
<B>ldap2dns</B> reduces all kind of administration overhead:
|
||||
No more flat file editing, no more zone file editing. After having installed
|
||||
<B>ldap2dns</B>, the administrator only has to access the LDAP directory.<BR>
|
||||
If he desires he can add access control for each zone, create a webbased GUI
|
||||
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.<BR>
|
||||
<B>ldap2dns</B> is designed to write binary data.cdb files used by tinydns, but
|
||||
also may be used to write .db-files used by named.<BR>
|
||||
<B>ldap2dns</B> is designed to write ASCII data files used by <I>tinydns</I>
|
||||
from the <I>djbdns</I> package, but also may be used to write .db-files used
|
||||
by <I>named</I> as found in the <I>BIND</I> package.<BR>
|
||||
<P>
|
||||
|
||||
<H3>1. Introduction</H3>
|
||||
@@ -22,7 +23,7 @@ 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.<BR>
|
||||
To solve this problem some proprietary attempts have been proposed to
|
||||
store DNS information in relational databases. The nature of DNS however
|
||||
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
|
||||
@@ -35,28 +36,28 @@ and generates a file suitable for name-servers.<BR>
|
||||
Actually the most widely spread name-servers
|
||||
<A HREF="http://www.isc.org/products/BIND/">named</A> and
|
||||
<A HREF="http://cr.yp.to/djbdns/tinydns.html">tinydns</A> are
|
||||
supported. <B>ldap2dns</B> has been specially designed to work with
|
||||
supported. <B>ldap2dns</B> specially has been designed to work with
|
||||
tinydns and is the favored name server daemon for the author of this program.
|
||||
<B>ldap2dns</B> can also generate files suitable for named, but this feature
|
||||
is not well supported.
|
||||
<B>ldap2dns</B> can also generate files suitable for <I>named</I> version 8,
|
||||
but this feature is not well supported.
|
||||
There is a
|
||||
<A HREF="http://www.alternic.org/drafts/drafts-m-n/draft-miller-dns-ldap-schema-00.txt">
|
||||
RFC</A> for a format description how to store DNS information in LDAP.
|
||||
This paper however is a draft RFC and expired in February 1999. The scheme this RFC
|
||||
describes, looks as if it has been designed to be used only by 'named'. This scheme
|
||||
This paper a draft RFC which expired in February 1999, looks as if it has been
|
||||
specially designed to be used by <I>named</I>. 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 (I have never heard of any).<BR>
|
||||
Since tinydns is going another descriptive way, I implemented a similar object-scheme
|
||||
more suitable for tinydns. Two objectclasses have been defined. <B>DNSzone</B> stores
|
||||
all the information to define a DNS zone, such as the SOA (Start Of Authority), serial
|
||||
numbers etc. <B>DNSrrset</B> is used to store the information for a single resource record,
|
||||
such as the domain name, IP-addresses, class and type.<BR>
|
||||
user interfaces. It also lacks of an implementation (or I have never heard of any).<BR>
|
||||
Since <I>tinydns</I> is going another descriptive way. Therefore I implemented a similar
|
||||
object-scheme more suitable for <I>tinydns</I>. Two object-classes have been defined.
|
||||
<B>DNSzone</B> stores all the information to define a DNS zone, such as the SOA
|
||||
(Start Of Authority), serial numbers etc. <B>DNSrrset</B> is used to store the information
|
||||
for a single resource record, such as the domain name, IP-addresses, class and type.<BR>
|
||||
Here are the tables:
|
||||
<P>
|
||||
<H4>DNSzone</H4>
|
||||
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!
|
||||
within a zone. Zones can be primary or secondary. If used in conjunction with
|
||||
<I>tinydns</I> 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 <B>DNSrrset</B>.<BR>
|
||||
@@ -79,26 +80,26 @@ can have none to many children of class <B>DNSrrset</B>.<BR>
|
||||
<TR><TD>DNStimestamp</TD><TD><I>timestamp</I></TD><TD>optional, only used with tinydns</TD></TR>
|
||||
</TABLE>
|
||||
<UL>
|
||||
<LI><B>DNSzonename:</B> This field is rquired to describe the zone's domain name, for instance
|
||||
<LI><B>DNSzonename:</B> This field is required to describe the zone's domain name, for instance
|
||||
myorg.com. More than one <B>DNSzonename</B> my be specified for a <B>DNSzone</B> so that the
|
||||
same host is accessable with different zonenames.</LI>
|
||||
|
||||
<LI><B>DNSserial:</B> This is the serial number as used for BIND's zone transfers. Here it is
|
||||
used to inform <B>ldap2dns</B> that it has to rebuild its data-file. Without increasing the serial
|
||||
number <B>ldap2dns</B> will do nothing.</LI>
|
||||
number <B>ldap2dns</B> will ignore all modifications until it is restarted.</LI>
|
||||
|
||||
<LI><B>DNSrefresh, DNSretry, DNSexpire, DNSminimum:</B> 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.</LI>
|
||||
|
||||
<LI><B>DNSzonemaster:</B> Here You specify the canonical name of Your primary nameserver.</LI>
|
||||
<LI><B>DNSzonemaster:</B> Here you specify the canonical name of your primary nameserver.</LI>
|
||||
|
||||
<LI><B>DNSadminmailbox:</B> This is the contact address of Your DNS-administrator. The first dot
|
||||
is converted to a <I>@</I>.</LI>
|
||||
|
||||
<LI><B>DNStype:</B> Must be <B>SOA</B> (which stands for Start Of Authority)</LI>
|
||||
<LI><B>DNStype:</B> Must be <B>SOA</B> (Start Of Authority)</LI>
|
||||
|
||||
<LI><B>DNSclass:</B> Must be <B>IN</B> (which stands for Internet, or do You have anything else?)</LI>
|
||||
<LI><B>DNSclass:</B> Must be <B>IN</B> (Internet, or do still use Chaosnet?)</LI>
|
||||
|
||||
<LI><B>DNSttl:</B> This is the time-to-live value as used by <B>tinydns</B>.
|
||||
If TTL is nonzero (or omitted), the timestamp is a starting time from whereon this zone's
|
||||
@@ -129,35 +130,36 @@ a given host name within a zone. It must be a child of a DNSzone object.<BR>
|
||||
<P>
|
||||
|
||||
<UL>
|
||||
<LI><B>DNSrrset:</B> This object-class must be a direct child of DNSzone. Its <B>dn</B> must be
|
||||
<LI><B>DNSrrset:</B> This object-class must be a direct child of DNSzone. Its <B>dn</B> should be
|
||||
specified as <PRE>cn=<I>domainname</I>,cn=<I>zonename</I>,...</PRE></LI>
|
||||
|
||||
<LI><B>DNSdomainname</B> This is the partial domainname, ie. the part in front of the
|
||||
zonename.</LI>
|
||||
<LI><B>DNSdomainname</B> This is the partial domain-name, ie. the part in front of the
|
||||
zone-name.</LI>
|
||||
|
||||
<LI><B>DNSipaddr:</B> This specifies the IP-address in dotted format. It can be used for <B>DNSrrset</B>'s
|
||||
of type <B>A, NS, MX</B> or <B>PTR</B>. <B>DNSipaddr</B> is multivalued to specifiy more than one
|
||||
IP-address for a service. If used in combination with <B>PTR</B> it overrides the old-fashioned form
|
||||
used in <B>DNSdomainname</B> such as 13.178.23.in-addr.arpa for reverse lookups.</LI>
|
||||
IP-address for a service. If used in <B>DNSrrset</B>'s with <B>DNStype</B> = <B>PTR</B> it
|
||||
overrides the old-fashioned form used in <B>DNSdomainname</B> such as 13.178.23.in-addr.arpa
|
||||
for reverse lookups.</LI>
|
||||
|
||||
<LI><B>DNScname:</B> Whereever there is a mapping of a domainname to a canonical name, use
|
||||
<LI><B>DNScname:</B> Whenever there is a mapping of a domain-name to a canonical name, use
|
||||
this attribute. <B>DNScname</B> may be used for <B>DNSrrset</B>'s with <B>DNStype CNAME,
|
||||
NS, MX, PTR or TXT</B>. If the last character of a CNAME is a dot its name is considered
|
||||
absolute. If it does not contain a dot, it name is prepended to the zonename.</LI>
|
||||
absolute. If it does not contain a dot, its name is prepended to the zone-name.</LI>
|
||||
|
||||
<LI><B>DNSpreference:</B> This number is the mail-exchange preference as used by BIND.</LI>
|
||||
|
||||
<LI><B>DNStype:</B> This must be <B>A, CNAME, NS, MX, PTR</B> or <B>TXT</B>. It specifies
|
||||
the DNSrrset type.</LI>
|
||||
|
||||
<LI><B>DNSclass:</B> Must be <B>IN</B> (which stands for Internet, or do You have anything else?)</LI>
|
||||
<LI><B>DNSclass:</B> Must be <B>IN</B></LI>
|
||||
|
||||
<LI><B>DNSttl:</B> This is the time-to-live value as used by <B>tinydns</B>.
|
||||
If TTL is nonzero (or omitted), the timestamp is a starting time from whereon this zone's
|
||||
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'').</LI>
|
||||
|
||||
<LI><B>DNStimestamp:</B> This is the timestamp as used by <B>tinydns</B>. It represents a
|
||||
string as external TAI64 timestamp, printed as 16 lowercase hexadecimal characters</LI>
|
||||
string as external TAI64 time-stamp, printed as 16 lowercase hexadecimal characters</LI>
|
||||
</UL>
|
||||
<P>
|
||||
|
||||
@@ -167,22 +169,25 @@ string as external TAI64 timestamp, printed as 16 lowercase hexadecimal characte
|
||||
LDAP implementations may work but have not been tested. Also install the
|
||||
development libraries and include files.</LI>
|
||||
|
||||
<LI>Install <A HREF="http://cr.yp.to/djbdns.html">djbdns</A> or if You really
|
||||
<LI>Install <A HREF="http://cr.yp.to/djbdns.html">djbdns</A> or if you really
|
||||
have to, go with BIND.<BR>
|
||||
I suggest to install tinydns included in the <B>djbdns</B> package, because it is
|
||||
I suggest to install <I>tinydns</I> included in the <B>djbdns</B> package, because it is
|
||||
safer, but You may have reasons why You want to use BIND.</LI>
|
||||
|
||||
<LI>Install <B>ldap2dns</B><BR>
|
||||
Unpack the package with gzcat ldap2dns.tar.gz | tar x
|
||||
If You use <B>tinydns</B> put the directory dns2ldap onto
|
||||
the same directory level where You have the directory dnscache.
|
||||
cd into the package and type make.</LI>
|
||||
Unpack the package and build it:
|
||||
<PRE>
|
||||
gzcat ldap2dns.tar.gz | tar x
|
||||
cd ldap2dns-version
|
||||
make
|
||||
make install
|
||||
</PRE>
|
||||
If you run <B>ldap2dns</B> togther with tinydns, go into
|
||||
/var/tinydns and run ldap2tinydns-conf.
|
||||
</LI>
|
||||
|
||||
<LI>If You do not want to use tinydns edit the Makefile,
|
||||
comment the lines starting with WITHTINYDNS and ALIBS. Then do a make.</LI>
|
||||
|
||||
<LI>Now add the extra object-classes to the slapd.conf file. To do this
|
||||
if You are using openldap-1.2.x:<BR>
|
||||
<LI>Add the extra object-classes to the slapd.conf file.
|
||||
If You are using openldap-1.2.x:<BR>
|
||||
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:<BR>
|
||||
<PRE>
|
||||
@@ -195,10 +200,10 @@ appropriate and add the following line to Your slapd.conf file:<BR>
|
||||
<PRE>
|
||||
include /etc/openldap/schema/dns.schema
|
||||
</PRE>
|
||||
Now restart Your LDAP server.</LI>
|
||||
Now restart your LDAP server.</LI>
|
||||
<P>
|
||||
|
||||
<LI>Start to populate Your LDAP server with DNS information, as a first test do
|
||||
<LI>Start to populate your LDAP server with DNS information. As a first test do
|
||||
<PRE>
|
||||
$ ldapadd -D "<I>binddn</I>" -w <I>password</I> < example.ldif
|
||||
</PRE>
|
||||
@@ -210,17 +215,13 @@ $ ldapsearch -D "<I>binddn</I>" "objectclass=dnsrrset" </LI>
|
||||
|
||||
<LI>Test <B>ldap2dns</B>
|
||||
<PRE>
|
||||
$ ./ldap2dns -D "<I>binddn</I>" [ -b "<I>searchbase</I>" ] [ -w <I>passwd</I> ] -o 7 -L
|
||||
$ ./ldap2dns -D "<I>binddn</I>" [ -b "<I>searchbase</I>" ] [ -w <I>passwd</I> ] -o data -o db -L
|
||||
</PRE>
|
||||
This should create a 'data' file, a 'data.cdb' file, a 'corp.local.db'
|
||||
file and should print the DNS content. If You disabled the tinydns
|
||||
option no 'data.cdb' file is generated.<BR>
|
||||
Note: The 'data' file is text data which can be processed with tinydns-data.
|
||||
The 'data.cdb' file is the binary version of 'data' processed as tinydns-data
|
||||
would. You must not restart tinydns to inform about the modification as You
|
||||
would have with named.<BR>
|
||||
'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. </LI>
|
||||
This should create a 'data' file, a 'corp.local.db' file and should print the
|
||||
DNS content.<BR>
|
||||
Note: The <I>data</I> file is text data which can be processed with <B>tinydns-data</B>.
|
||||
<I>corp.local.db</I> is the file as used by <B>named</B>. If You are using bind, You also
|
||||
have to adopt the file <I>/etc/named.conf</I> and You have to restart named.</LI>
|
||||
</UL>
|
||||
<P>
|
||||
|
||||
@@ -229,10 +230,12 @@ If You are a tinydns user, run <B>ldap2dns</B> in /services/tinydns/root.<BR>
|
||||
If You are an openldap user, the command line switches are the same as for ldapsearch
|
||||
or ldapadd.
|
||||
<PRE>
|
||||
$ ldap2dns -D "<I>binddn</I>" [ -w <I>passwd</I> ] -b "<I>searchbase</I>" -o 1
|
||||
$ ldap2dns -D "<I>binddn</I>" [ -w <I>passwd</I> ] -b "<I>searchbase</I>" -o data -e "cd /var/tinydns/root && /usr/bin/tinydns-data"
|
||||
</PRE>
|
||||
This generates a data.cdb file which is automatically updated by tinydns. The password
|
||||
is required if You restrict read queries to authenticated users only. Now test with
|
||||
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
|
||||
<PRE>
|
||||
$ dnsq any corp.local <I>ipaddr</I>
|
||||
</PRE>
|
||||
@@ -241,10 +244,11 @@ Replace <I>ipaddr</I> with whatever You configured tinydns to listen to.
|
||||
|
||||
If You are a BIND user, run <B>ldap2dns</B> in /var/named with
|
||||
<PRE>
|
||||
$ ldap2dns -D "<I>binddn</I>" -w <I>passwd</I> -b "<I>searchbase</I>" -o 4
|
||||
$ ldap2dns -D "<I>binddn</I>" -w <I>passwd</I> -b "<I>searchbase</I>" -o db -e "kill -HUP `cat /var/run/named-pid`"
|
||||
</PRE>
|
||||
Do not forget to add You primary definition to Your named.boot file and
|
||||
do not forget to restart named with
|
||||
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
|
||||
<PRE>
|
||||
# kill -HUP <I>PID</I>
|
||||
</PRE>
|
||||
@@ -253,15 +257,16 @@ Now run
|
||||
$ nslookup - localhost
|
||||
> ns1.corp.local
|
||||
</PRE>
|
||||
Note that nslookup only works with tinydns if Your nameserver resolves its IP-address
|
||||
Note that <B>nslookup</B> only works with <B>tinydns</B> if Your nameserver resolves its IP-address
|
||||
backwards.
|
||||
<P>
|
||||
|
||||
<H3>4. Running ldap2dnsd</H3>
|
||||
<B>ldap2dnsd</B> is a hard link onto <B>ldap2dns</B>. If invoked the program
|
||||
<B>ldap2dnsd</B> is a hard link onto <B>ldap2dns</B>. 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 <B>DNSserial</B> numbers it updates the data.cdb
|
||||
file. This check is done about once a minute.<BR>
|
||||
If the the daemon sees a modification in the <B>DNSserial</B> numbers it updates the data
|
||||
or .db files, depending what kind of output was configured. This check is done about once
|
||||
a minute.<BR>
|
||||
The command-line options for <B>ldap2dnsd</B> are the same as for <B>ldap2dns</B>.
|
||||
Use the -u option to modify the update intervall. You may also use -u on <B>ldap2dns</B>
|
||||
to start as a foreground daemon. This is useful if You want to run <B>ldap2dns</B> from
|
||||
@@ -270,7 +275,7 @@ in /service/tinydns and link /service/ldap2dns onto /service/tinydns/ldap2dns.
|
||||
<PRE>
|
||||
# ln -s /service/tinydns/ldap2dns /service/ldap2dns
|
||||
</PRE>
|
||||
After a few seconds <B>daemontools</B> starts <B>ldap2dns</B> which itself generates data.cdb
|
||||
After a few seconds <B>daemontools</B> starts <B>ldap2dns</B> which itself generates data
|
||||
files whenever a modification is commited into the LDAP directory.
|
||||
<P>
|
||||
<B>ldap2dns</B> and <B>ldap2dnsd</B> recognize the following options:
|
||||
@@ -278,22 +283,30 @@ files whenever a modification is commited into the LDAP directory.
|
||||
-D <I>binddn</I> specify the distinguished name to bind to the LDAP directory
|
||||
-w <I>bindpasswd</I> use bindpasswd as the password for simple authentication
|
||||
-b <I>searchbase</I> use searchbase as the starting point for the search instead of the default
|
||||
-o 1|2|4 output format number or any binary or-ed combination. Defaults to 1
|
||||
1: generate a binary file named 'data.cdb' to be used directly by tinydns
|
||||
2: generate a text file named 'data' to be parsed by tinydns-data
|
||||
4: for each zone generate a file named '<zonename>.db' to be used by named
|
||||
-L[<I>filename</I>] print output in LDIF format for reimport, defaults to stdout if filename is omitted
|
||||
-h <I>host</I> specify the hostname of LDAP directory, defaults to localhost
|
||||
-p <I>port</I> portnumber to connect to LDAP directory, defaults to 389
|
||||
-o Generate a "data" file to be processed by tinydns-data.
|
||||
-o db For each zone generate a "<zonename>.db" file to be used by named.
|
||||
-L[<I>filename</I>] print output in LDIF format for reimport. If no filename is specified output goes to stdout.
|
||||
-h <I>host</I> specify the hostname of LDAP directory. Default is localhost.
|
||||
-p <I>port</I> portnumber to connect to LDAP directory. Defaults is 389
|
||||
-v run in verbose mode
|
||||
-vv even more verbose
|
||||
-V print version and exit
|
||||
-u <I>numsecs</I> update DNS data every numsecs. If started as ldap2dnsd this defaults to 59.
|
||||
-u <I>numsecs</I> update DNS data every numsecs.
|
||||
</PRE>
|
||||
<B>ldap2dns</B> and <B>ldap2dnsd</B> recognizes the following environement variables:<BR>
|
||||
<B>TINYDNSDIR</B>: Specifies the directory where ldap2dns writes its data file.<BR>
|
||||
<B>LDAP2DNS_UPDATE</B>: Specifies the update intervall as the -u command line option would.<BR>
|
||||
<B>LDAP2DNS_OUTPUT</B>: Specifies the default output, as the -o command line option would.
|
||||
<P>
|
||||
<B>ldap2dns</B> and <B>ldap2dnsd</B> use the following parameters from /etc/ldap.conf if not
|
||||
specified on the command line:
|
||||
<B>BASE</B>: The LDAP search base.<BR>
|
||||
<B>HOST</B>: The LDAP server.<BR>
|
||||
<B>PORT</B>: The LDAP port.
|
||||
<P>
|
||||
|
||||
<H3>5. Importing DNS data from Your named</H3>
|
||||
A perl-script 'import.pl' is contained in this package. Edit the first
|
||||
A perl-script <I>import.pl</I> 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
|
||||
@@ -303,7 +316,7 @@ skip the following lines, otherwise do
|
||||
> install Net::DNS
|
||||
> install Net::LDAP
|
||||
</PRE>
|
||||
Now check that Your nameserver allows zone transfers to Your host and run the import script:
|
||||
Now check that Your nameserver allows zone transfers to your host and run the import script:
|
||||
<PRE>
|
||||
$ echo 'primary mydomain.org ' | ./import.pl
|
||||
</PRE>
|
||||
@@ -314,19 +327,17 @@ for a single domain or
|
||||
to populate Your LDAP directory.
|
||||
<P>
|
||||
|
||||
<H3>5. To Do</H3>
|
||||
<H3>6. To Do</H3>
|
||||
<UL>
|
||||
<LI>Write a man page.</LI>
|
||||
<LI><B>named</B> should be restarted automatically sending a HUP signal to the appropriate daemon.</LI>
|
||||
<LI>named.conf should be created automatically.</LI>
|
||||
<LI>The option -o is not very nice.</LI>
|
||||
</UL>
|
||||
<P>
|
||||
|
||||
<H3>6. Copyright</H3>
|
||||
<H3>7. Copyright and disclaimer</H3>
|
||||
This program is licensed under the GPL version 2 or at Your choice any later
|
||||
version.<BR>
|
||||
It was written in autumn 2000 by
|
||||
<A HREF="mailto:jacob.rief@bigfoot.com?subject=ldap2dns">Jacob Rief</A>
|
||||
in the hope it may be useful.
|
||||
It is maintained by <A HREF="mailto:jacob.rief@tiscover.com?subject=ldap2dns">Jacob Rief</A>.
|
||||
If you run <B>ldap2dns</B> on a productive nameserver, please mail me
|
||||
and tell me on what OS and with which nameserver you do so.
|
||||
|
||||
|
||||
11
Specfile
11
Specfile
@@ -24,15 +24,18 @@ ldap2dns is designed to write binary data.cdb files used by tinydns, but also ma
|
||||
used to write .db-files used by named.
|
||||
|
||||
%prep
|
||||
%setup -a1 -q
|
||||
#%setup -a1 -q
|
||||
%setup
|
||||
|
||||
%build
|
||||
make -C %{djbdns}
|
||||
make DJBDNSDIR="%{djbdns}" VERSION=%{version} RPM_OPT_FLAGS="$RPM_OPT_FLAGS"
|
||||
#make -C %{djbdns}
|
||||
#make DJBDNSDIR="%{djbdns}" VERSION=%{version} RPM_OPT_FLAGS="$RPM_OPT_FLAGS"
|
||||
make VERSION=%{version} RPM_OPT_FLAGS="$RPM_OPT_FLAGS"
|
||||
|
||||
%install
|
||||
[ -n "%{buildroot}" -a "%{buildroot}" != / ] && rm -rf %{buildroot}
|
||||
make DJBDNSDIR="%{djbdns}" INSTALL_PREFIX=$RPM_BUILD_ROOT install
|
||||
#make DJBDNSDIR="%{djbdns}" INSTALL_PREFIX=$RPM_BUILD_ROOT install
|
||||
make INSTALL_PREFIX=$RPM_BUILD_ROOT install
|
||||
|
||||
%clean
|
||||
[ -n "%{buildroot}" -a "%{buildroot}" != / ] && rm -rf %{buildroot}
|
||||
|
||||
3
TODO
Normal file
3
TODO
Normal file
@@ -0,0 +1,3 @@
|
||||
- Use env-variable LDAP2DNS_UPDATE for update intervalls
|
||||
- If connection to ldapserver fialed retry later
|
||||
|
||||
12
dns.schema
12
dns.schema
@@ -1,6 +1,6 @@
|
||||
# schema for DNS data
|
||||
# include this file into Your slapd.conf for openldap-2.0.x
|
||||
# $Id: dns.schema,v 1.3 2000/12/01 14:48:25 jrief Exp $
|
||||
# $Id: dns.schema,v 1.4 2001/02/16 09:51:23 jrief Exp $
|
||||
|
||||
attributetype ( 1.2.840.113556.1.17.1
|
||||
NAME 'DNSzonename'
|
||||
@@ -98,14 +98,14 @@ attributetype ( 1.2.840.113556.1.17.20
|
||||
objectclass ( 1.2.840.113556.1.17.21
|
||||
NAME 'DNSzone'
|
||||
MUST ( objectclass $ cn )
|
||||
MAY ( zonedomainname $ serial $ refresh $ retry $ expire $ minimum
|
||||
$ adminmailbox $ zonemaster $ zonetype $ zoneclass $ rrcount
|
||||
$ ttl $ timestamp ) )
|
||||
MAY ( DNSdomainname $ DNSserial $ DNSrefresh $ DNSretry $ DNSexpire $ DNSminimum
|
||||
$ DNSadminmailbox $ DNSzonemaster $ DNSzonetype $ DNSzoneclass $ DNSrrcount
|
||||
$ DNSttl $ DNStimestamp ) )
|
||||
|
||||
objectclass ( 1.2.840.113556.1.17.22
|
||||
NAME 'DNSrrset'
|
||||
SUP DNSzone
|
||||
MUST ( objectclass $ cn )
|
||||
MAY ( dnsdomainname $ aliasedobjectname $ rr $ macaddress $ zoneclass
|
||||
$ zonetype $ ipaddr $ cname $ preference $ ttl $ timestamp ) )
|
||||
MAY ( DNSdomainname $ DNSaliasedobjectname $ DNSrr $ DNSmacaddress $ DNSclass
|
||||
$ DNStype $ DNSipaddr $ DNScname $ DNSpreference $ DNSttl $ DNStimestamp ) )
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
>
|
||||
<BLOCKQUOTE>
|
||||
<P>
|
||||
<!--#include file="README.html"--->
|
||||
<!--#include file="ldap2dns/README.html"-->
|
||||
<P>
|
||||
<H3 align=center>Download</H3>
|
||||
<TABLE border=2 cellpadding=4 align=center>
|
||||
@@ -33,6 +33,7 @@
|
||||
<TR align=center><TD>0.1.3</TD><TD><A HREF="ldap2dns-0.1.3.tar.gz">ldap2dns</A></TD><TD></TD><TD></TD><TD>2000-Sep-28</TD></TR>
|
||||
<TR align=center><TD>0.1.4</TD><TD><A HREF="ldap2dns-0.1.4.tar.gz">ldap2dns</A></TD><TD></TD><TD></TD><TD>2000-Oct-04</TD></TR>
|
||||
<TR align=center><TD>0.2.0</TD><TD><A HREF="ldap2dns-0.2.0.tar.gz">ldap2dns</A></TD><TD><A HREF="ldap2dns-0.2.0-1.i386.rpm">ldap2dns</A></TD><TD><A HREF="ldap2dns-0.2.0-1.src.rpm">ldap2dns</A></TD><TD>2000-Dec-14</TD></TR>
|
||||
<TR align=center><TD>0.2.2</TD><TD><A HREF="ldap2dns-0.2.2.tar.gz">ldap2dns</A></TD><TD><A HREF="ldap2dns-0.2.2-2.i386.rpm">ldap2dns</A></TD><TD><A HREF="ldap2dns-0.2.2-2.src.rpm">ldap2dns</A></TD><TD>2001-Feb-16</TD></TR>
|
||||
</TABLE>
|
||||
|
||||
</BLOCKQUOTE>
|
||||
|
||||
434
ldap2dns.c
434
ldap2dns.c
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Create data from an LDAP directory service to be used for tinydns
|
||||
* $Id: ldap2dns.c,v 1.20 2000/12/12 09:48:07 jrief Exp $
|
||||
* $Id: ldap2dns.c,v 1.26 2001/02/27 10:08:31 jrief Exp $
|
||||
* Copyright 2000 by Jacob Rief <jacob.rief@tiscover.com>
|
||||
* License: GPL version 2 or later. See http://www.fsf.org for details
|
||||
*/
|
||||
@@ -15,44 +15,17 @@
|
||||
|
||||
#define UPDATE_INTERVALL 59
|
||||
#define LDAP_CONF "/etc/openldap/ldap.conf"
|
||||
|
||||
#if defined WITH_TINYDNS
|
||||
# include "uint16.h"
|
||||
# include "uint32.h"
|
||||
# include "str.h"
|
||||
# include "byte.h"
|
||||
# include "fmt.h"
|
||||
# include "ip4.h"
|
||||
# include "exit.h"
|
||||
# include "readwrite.h"
|
||||
# include "buffer.h"
|
||||
# include "strerr.h"
|
||||
# include "getln.h"
|
||||
# include "cdb_make.h"
|
||||
# include "stralloc.h"
|
||||
# include "open.h"
|
||||
# include "dns.h"
|
||||
|
||||
int fdcdb;
|
||||
struct cdb_make cdb;
|
||||
buffer b;
|
||||
char bspace[1024];
|
||||
static stralloc key;
|
||||
static stralloc result;
|
||||
static char* dottemp1;
|
||||
static char* dottemp2;
|
||||
static char tinydns_datafile[256];
|
||||
static char tinydns_tempfile[256];
|
||||
|
||||
#endif
|
||||
#define OUTPUT_DATA 1
|
||||
#define OUTPUT_DB 2
|
||||
|
||||
static char tinydns_textfile[256];
|
||||
static char tinydns_texttemp[256];
|
||||
static LDAP* ldap_con;
|
||||
static FILE* bindfile;
|
||||
static FILE* namedmaster;
|
||||
static FILE* namedzone;
|
||||
static FILE* tinyfile;
|
||||
static FILE* ldifout;
|
||||
static time_t time_now;
|
||||
static int autoreverse;
|
||||
static char* const* main_argv;
|
||||
static int main_argc;
|
||||
|
||||
@@ -75,14 +48,15 @@ static struct
|
||||
{
|
||||
char domainname[64];
|
||||
char zonemaster[64];
|
||||
char class[16];
|
||||
char adminmailbox[64];
|
||||
unsigned long serial;
|
||||
unsigned long refresh;
|
||||
unsigned long retry;
|
||||
unsigned long expire;
|
||||
unsigned long minimum;
|
||||
char timestamp[20];
|
||||
int ttl;
|
||||
char timestamp[16];
|
||||
} zone;
|
||||
|
||||
struct resourcerecord
|
||||
@@ -92,9 +66,10 @@ struct resourcerecord
|
||||
char class[16];
|
||||
char type[16];
|
||||
char ipaddr[256][32];
|
||||
char cipaddr[32];
|
||||
char cname[64];
|
||||
char timestamp[20];
|
||||
int ttl;
|
||||
char timestamp[16];
|
||||
int preference;
|
||||
#if defined DRAFT_RFC
|
||||
char rr[1024];
|
||||
@@ -116,6 +91,7 @@ static struct
|
||||
unsigned int output;
|
||||
int verbose;
|
||||
char ldifname[128];
|
||||
char exec_command[128];
|
||||
} options;
|
||||
|
||||
|
||||
@@ -129,96 +105,46 @@ static void die_exit(const char* message)
|
||||
}
|
||||
|
||||
|
||||
#if defined WITH_TINYDNS
|
||||
|
||||
static void rr_add(char *buf, unsigned int len)
|
||||
{
|
||||
if (!stralloc_catb(&result, buf, len)) die_exit(0);
|
||||
}
|
||||
|
||||
static void rr_addname(char *d)
|
||||
{
|
||||
rr_add(d,dns_domain_length(d));
|
||||
}
|
||||
|
||||
static void rr_start(char type[2], unsigned long ttl, char ttd[8])
|
||||
{
|
||||
char buf[4];
|
||||
if (!stralloc_copyb(&result, type,2)) die_exit(0);
|
||||
rr_add("=",1);
|
||||
uint32_pack_big(buf, ttl);
|
||||
rr_add(buf,4);
|
||||
rr_add(ttd,8);
|
||||
}
|
||||
|
||||
static void rr_finish(char *owner)
|
||||
{
|
||||
if (byte_equal(owner,2,"\1*")) {
|
||||
owner += 2;
|
||||
result.s[2] = '*';
|
||||
}
|
||||
if (!stralloc_copyb(&key, owner, dns_domain_length(owner))) die_exit(0);
|
||||
case_lowerb(key.s, key.len);
|
||||
if (cdb_make_add(&cdb, key.s, key.len, result.s, result.len) == -1)
|
||||
die_exit("Unable to create 'data.tmp'");
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
static void set_datadir(void)
|
||||
{
|
||||
char* ev = getenv("TINYDNSDIR");
|
||||
int len;
|
||||
|
||||
#if defined WITH_TINYDNS
|
||||
tinydns_datafile[0] = 0;
|
||||
tinydns_tempfile[0] = 0;
|
||||
#endif
|
||||
tinydns_textfile[0] = 0;
|
||||
tinydns_textfile[0] = '\0';
|
||||
tinydns_texttemp[0] = '\0';
|
||||
if (ev && (len = strlen(ev))<240) {
|
||||
#if defined WITH_TINYDNS
|
||||
strncpy(tinydns_datafile, ev, 240);
|
||||
strncpy(tinydns_tempfile, ev, 240);
|
||||
#endif
|
||||
strncpy(tinydns_textfile, ev, 240);
|
||||
strncpy(tinydns_texttemp, ev, 240);
|
||||
if (ev[len-1]!='/') {
|
||||
#if defined WITH_TINYDNS
|
||||
tinydns_datafile[len] = '/';
|
||||
tinydns_tempfile[len] = '/';
|
||||
#endif
|
||||
tinydns_textfile[len] = '/';
|
||||
tinydns_texttemp[len] = '/';
|
||||
}
|
||||
}
|
||||
#if defined WITH_TINYDNS
|
||||
strcat(tinydns_datafile, "data.cdb");
|
||||
strcat(tinydns_tempfile, "data.tmp");
|
||||
#endif
|
||||
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 0|1|2|4] [-h host] [-p port] [-w password] [-L[filename]] [-u numsecs] [-v[v]] [-V]\n\n");
|
||||
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 1|2|4\toutput format number or any binary or-ed combination. Defaults to 1\n");
|
||||
printf("\t1: generate a binary file named 'data.cdb' to be used directly by tinydns\n");
|
||||
printf("\t2: generate a text file named 'data' to be parsed by tinydns-data\n");
|
||||
printf("\t4: for each zone generate a file named '<zonename>.db' 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(" -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 \"<zonename>.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");
|
||||
@@ -229,8 +155,9 @@ static int parse_options()
|
||||
extern char* optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
char buf[256], value[128];
|
||||
int c;
|
||||
int len;
|
||||
FILE* ldap_conf;
|
||||
char* ev;
|
||||
|
||||
strcpy(options.searchbase, "");
|
||||
strcpy(options.hostname, "localhost");
|
||||
@@ -239,33 +166,46 @@ static int parse_options()
|
||||
while(fgets(buf, 256, ldap_conf)!=0) {
|
||||
if (sscanf(buf, "BASE %128s", value)==1)
|
||||
strcpy(options.searchbase, value);
|
||||
if (sscanf(buf, "HOST %128s:%d", value, &c)==2) {
|
||||
if (sscanf(buf, "HOST %128s:%d", value, &len)==2) {
|
||||
strcpy(options.hostname, value);
|
||||
options.port = c;
|
||||
options.port = len;
|
||||
} else if (sscanf(buf, "HOST %128s", value)==1)
|
||||
strcpy(options.hostname, value);
|
||||
if (sscanf(buf, "PORT %d", &c)==1)
|
||||
options.port = c;
|
||||
if (sscanf(buf, "PORT %d", &len)==1)
|
||||
options.port = len;
|
||||
}
|
||||
fclose(ldap_conf);
|
||||
}
|
||||
strcpy(options.binddn, "");
|
||||
options.output = 1;
|
||||
len = strlen(main_argv[0]);
|
||||
if (strcmp(main_argv[0]+len-9, "ldap2dnsd")==0) {
|
||||
options.is_daemon = 1;
|
||||
options.update_iv = UPDATE_INTERVALL;
|
||||
} else {
|
||||
options.is_daemon = 0;
|
||||
options.update_iv = 0;
|
||||
}
|
||||
ev = getenv("LDAP2DNS_UPDATE");
|
||||
if (ev && sscanf(ev, "%d", &len)==1 && len>0)
|
||||
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;
|
||||
}
|
||||
options.verbose = 0;
|
||||
options.ldifname[0] = '\0';
|
||||
c = strlen(main_argv[0]);
|
||||
if (strcmp(main_argv[0]+c-9, "ldap2dnsd")==0)
|
||||
options.is_daemon = 1;
|
||||
else
|
||||
options.is_daemon = 0;
|
||||
options.update_iv = 59;
|
||||
strcpy(options.password, "");
|
||||
while ( (c = getopt(main_argc, main_argv, "b:D:h:o:p:u:Vw:v::L::"))>0 ) {
|
||||
strcpy(options.exec_command, "");
|
||||
while ( (len = getopt(main_argc, main_argv, "b:D:e:h:o:p:u:Vw:v::L::"))>0 ) {
|
||||
if (optarg && strlen(optarg)>127) {
|
||||
fprintf(stderr, "argument %s too long\n", optarg);
|
||||
continue;
|
||||
}
|
||||
switch (c) {
|
||||
switch (len) {
|
||||
case 'b':
|
||||
strcpy(options.searchbase, optarg);
|
||||
break;
|
||||
@@ -273,7 +213,6 @@ static int parse_options()
|
||||
if (sscanf(optarg, "%d", &options.update_iv)!=1)
|
||||
options.update_iv = UPDATE_INTERVALL;
|
||||
if (options.update_iv<=0) options.update_iv = 1;
|
||||
if (options.is_daemon==0) options.is_daemon = 2; /* foreground daemon */
|
||||
break;
|
||||
case 'D':
|
||||
strcpy(options.binddn, optarg);
|
||||
@@ -288,8 +227,10 @@ static int parse_options()
|
||||
strcpy(options.ldifname, optarg);
|
||||
break;
|
||||
case 'o':
|
||||
if (sscanf(optarg, "%d", &options.output)!=1)
|
||||
options.output = 0;
|
||||
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)!=1)
|
||||
@@ -307,11 +248,16 @@ static int parse_options()
|
||||
case 'w':
|
||||
strcpy(options.password, optarg);
|
||||
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 */
|
||||
}
|
||||
|
||||
|
||||
@@ -341,86 +287,74 @@ static int expand_reverse(char target[64], const char* source)
|
||||
}
|
||||
|
||||
|
||||
static void write_rr(struct resourcerecord* rr, int ipdx)
|
||||
static void write_rr(struct resourcerecord* rr, int ipdx, int znix)
|
||||
{
|
||||
char ip[4];
|
||||
char buf[4];
|
||||
|
||||
if (strcasecmp(rr->class, "IN"))
|
||||
return;
|
||||
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
int dnsdn_len = strlen(rr->dnsdomainname);
|
||||
int cname_len = strlen(rr->cname);
|
||||
if (!dns_domain_fromdot(&dottemp1, rr->dnsdomainname, dnsdn_len)) die_exit(0);
|
||||
if (!dns_domain_fromdot(&dottemp2, rr->cname, cname_len)) die_exit(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strcasecmp(rr->type, "NS")==0) {
|
||||
if (tinyfile)
|
||||
fprintf(tinyfile, "&%s:%s:%s:%d:%s\n", rr->dnsdomainname, (ipdx>=0 ? rr->ipaddr[ipdx] : ""), rr->cname, rr->ttl, rr->timestamp);
|
||||
if (bindfile) {
|
||||
fprintf(bindfile, "%s.\tIN NS\t%s.\n", rr->dnsdomainname, rr->cname);
|
||||
if (ipdx>=0)
|
||||
fprintf(bindfile, "%s.\tIN A\t%s\n", rr->cname, rr->ipaddr[ipdx]);
|
||||
}
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
rr_start(DNS_T_NS, rr->ttl, rr->timestamp);
|
||||
rr_addname(dottemp2);
|
||||
rr_finish(dottemp1);
|
||||
if (ipdx>=0 && ip4_scan(rr->ipaddr[ipdx], ip)) {
|
||||
rr_start(DNS_T_A, rr->ttl, rr->timestamp);
|
||||
rr_add(ip, 4);
|
||||
rr_finish(dottemp2);
|
||||
if (tinyfile) {
|
||||
if (znix==0) {
|
||||
if (ipdx<=0 && rr->cipaddr[0]) {
|
||||
fprintf(tinyfile, "&%s::%s:%d:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp);
|
||||
if (rr->cname[0])
|
||||
fprintf(tinyfile, "=%s:%s:%d:%s\n", rr->cname, rr->cipaddr, rr->ttl, rr->timestamp);
|
||||
if (ipdx==0)
|
||||
fprintf(tinyfile, "+%s:%s:%d:%s\n", rr->cname, rr->ipaddr[0], rr->ttl, rr->timestamp);
|
||||
} else if (ipdx<0)
|
||||
fprintf(tinyfile, "&%s::%s:%d:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp);
|
||||
else if (ipdx==0)
|
||||
fprintf(tinyfile, "&%s:%s:%s:%d:%s\n", rr->dnsdomainname, rr->ipaddr[0], rr->cname, rr->ttl, rr->timestamp);
|
||||
else if (ipdx>0 && rr->cname[0])
|
||||
fprintf(tinyfile, "+%s:%s:%d:%s\n", rr->cname, rr->ipaddr[ipdx], rr->ttl, rr->timestamp);
|
||||
} else if (ipdx<=0) {
|
||||
fprintf(tinyfile, "&%s::%s:%d:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
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)
|
||||
fprintf(tinyfile, "@%s:%s:%s:%d:%d:%s\n", rr->dnsdomainname, (ipdx>=0 ? rr->ipaddr[ipdx] : ""), rr->cname, rr->preference, rr->ttl, rr->timestamp);
|
||||
if (bindfile) {
|
||||
fprintf(bindfile, "%s.\tIN MX\t%d %s.\n", rr->dnsdomainname, rr->preference, rr->cname);
|
||||
if (tinyfile) {
|
||||
if (znix==0) {
|
||||
if (ipdx<=0 && rr->cipaddr[0]) {
|
||||
fprintf(tinyfile, "@%s::%s:%d:%d:%s\n", rr->dnsdomainname, rr->cname, rr->preference, rr->ttl, rr->timestamp);
|
||||
if (rr->cname[0])
|
||||
fprintf(tinyfile, "=%s:%s:%d:%s\n", rr->cname, rr->cipaddr, rr->ttl, rr->timestamp);
|
||||
if (ipdx==0)
|
||||
fprintf(tinyfile, "+%s:%s:%d:%s\n", rr->cname, rr->ipaddr[0], rr->ttl, rr->timestamp);
|
||||
} else if (ipdx<0)
|
||||
fprintf(tinyfile, "@%s::%s:%d:%d:%s\n", rr->dnsdomainname, rr->cname, rr->preference, rr->ttl, rr->timestamp);
|
||||
else if (ipdx==0)
|
||||
fprintf(tinyfile, "@%s:%s:%s:%d:%d:%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:%d:%s\n", rr->cname, rr->ipaddr[ipdx], rr->ttl, rr->timestamp);
|
||||
} else if (ipdx<=0) {
|
||||
fprintf(tinyfile, "@%s::%s:%d:%d:%s\n", rr->dnsdomainname, rr->cname, rr->preference, rr->ttl, rr->timestamp);
|
||||
}
|
||||
}
|
||||
if (namedzone) {
|
||||
fprintf(namedzone, "%s.\tIN MX\t%d %s.\n", rr->dnsdomainname, rr->preference, rr->cname);
|
||||
if (ipdx>=0)
|
||||
fprintf(bindfile, "%s.\tIN A\t%s\n", rr->cname, rr->ipaddr[ipdx]);
|
||||
fprintf(namedzone, "%s.\tIN A\t%s\n", rr->cname, rr->ipaddr[ipdx]);
|
||||
}
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
rr_start(DNS_T_MX, rr->ttl, rr->timestamp);
|
||||
uint16_pack_big(buf, rr->preference);
|
||||
rr_add(buf, 2);
|
||||
rr_addname(dottemp2);
|
||||
rr_finish(dottemp1);
|
||||
if (ipdx>=0 && ip4_scan(rr->ipaddr[ipdx], ip)) {
|
||||
rr_start(DNS_T_A, rr->ttl, rr->timestamp);
|
||||
rr_add(ip, 4);
|
||||
rr_finish(dottemp2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} else if ( strcasecmp(rr->type, "A")==0) {
|
||||
if (tinyfile)
|
||||
fprintf(tinyfile, "%s%s:%s:%d:%s\n", (autoreverse ? "=" : "+"), rr->dnsdomainname, (ipdx>=0 ? rr->ipaddr[ipdx] : ""), rr->ttl, rr->timestamp);
|
||||
if (bindfile && ipdx>=0)
|
||||
fprintf(bindfile, "%s.\tIN A\t%s\n", rr->dnsdomainname, rr->ipaddr[ipdx]);
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
char dptr[DNS_NAME4_DOMAIN];
|
||||
if (ipdx>=0 && ip4_scan(rr->ipaddr[ipdx], ip)) {
|
||||
rr_start(DNS_T_A, rr->ttl, rr->timestamp);
|
||||
rr_add(ip, 4);
|
||||
rr_finish(dottemp1);
|
||||
}
|
||||
if (autoreverse) {
|
||||
dns_name4_domain(dptr, ip);
|
||||
rr_start(DNS_T_PTR, rr->ttl, rr->timestamp);
|
||||
rr_addname(dottemp1);
|
||||
rr_finish(dptr);
|
||||
}
|
||||
if (tinyfile) {
|
||||
if (ipdx<=0 && rr->cipaddr[0])
|
||||
fprintf(tinyfile, "%s%s:%s:%d:%s\n", (znix==0 ? "=" : "+"), rr->dnsdomainname, rr->cipaddr, rr->ttl, rr->timestamp);
|
||||
if (ipdx>=0)
|
||||
fprintf(tinyfile, "+%s:%s:%d:%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]);
|
||||
}
|
||||
#endif
|
||||
} else if (strcasecmp(rr->type, "PTR")==0) {
|
||||
int ip[4] = {0, 0, 0, 0};
|
||||
char buf[64];
|
||||
@@ -436,41 +370,18 @@ static void write_rr(struct resourcerecord* rr, int ipdx)
|
||||
}
|
||||
if (tinyfile)
|
||||
fprintf(tinyfile, "^%s:%s:%d:%s\n", buf, rr->cname, rr->ttl, rr->timestamp);
|
||||
if (bindfile)
|
||||
fprintf(bindfile, "%s.\tIN PTR\t%s.\n", buf, rr->cname);
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
int dnsdn_len = strlen(buf);
|
||||
if (!dns_domain_fromdot(&dottemp1, buf, dnsdn_len)) die_exit(0);
|
||||
rr_start(DNS_T_PTR, rr->ttl, rr->timestamp);
|
||||
rr_addname(dottemp2);
|
||||
rr_finish(dottemp1);
|
||||
}
|
||||
#endif
|
||||
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:%d:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp);
|
||||
if (bindfile)
|
||||
fprintf(bindfile, "%s.\tIN CNAME\t%s.\n", rr->dnsdomainname, rr->cname);
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
rr_start(DNS_T_CNAME, rr->ttl, rr->timestamp);
|
||||
rr_addname(dottemp2);
|
||||
rr_finish(dottemp1);
|
||||
}
|
||||
#endif
|
||||
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:%d:%s\n", rr->dnsdomainname, rr->cname, rr->ttl, rr->timestamp);
|
||||
if (bindfile)
|
||||
fprintf(bindfile, "%s.\tIN TXT\t%s.\n", rr->dnsdomainname, rr->cname);
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
rr_start(DNS_T_TXT, rr->ttl, rr->timestamp);
|
||||
rr_addname(dottemp2);
|
||||
rr_finish(dottemp1);
|
||||
}
|
||||
#endif
|
||||
if (namedzone)
|
||||
fprintf(namedzone, "%s.\tIN TXT\t%s.\n", rr->dnsdomainname, rr->cname);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,7 +427,7 @@ static void parse_rr(struct resourcerecord* rr)
|
||||
#endif
|
||||
|
||||
|
||||
static void read_resourcerecords(char* dn)
|
||||
static void read_resourcerecords(char* dn, int znix)
|
||||
{
|
||||
LDAPMessage* res = NULL;
|
||||
LDAPMessage* m;
|
||||
@@ -535,9 +446,10 @@ static void read_resourcerecords(char* dn)
|
||||
fprintf(ldifout, "dn: %s\n", dn);
|
||||
rr.cn[0] = '\0';
|
||||
strncpy(rr.dnsdomainname, zone.domainname, 64);
|
||||
strcpy(rr.class, "IN");
|
||||
strncpy(rr.class, "IN", 3);
|
||||
rr.type[0] = '\0';
|
||||
rr.cname[0] = '\0';
|
||||
rr.cipaddr[0] = '\0';
|
||||
rr.ttl = time_now;
|
||||
rr.timestamp[0] = '\0';
|
||||
rr.preference = 10;
|
||||
@@ -583,6 +495,12 @@ static void read_resourcerecords(char* dn)
|
||||
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';
|
||||
@@ -628,7 +546,7 @@ static void read_resourcerecords(char* dn)
|
||||
#endif
|
||||
do {
|
||||
ipaddresses--;
|
||||
write_rr(&rr, ipaddresses);
|
||||
write_rr(&rr, ipaddresses, znix);
|
||||
} while (ipaddresses>0);
|
||||
#if defined DRAFT_RFC
|
||||
if (rr.aliasedobjectname[0])
|
||||
@@ -654,34 +572,20 @@ static void write_zone(void)
|
||||
zone.zonemaster, zone.adminmailbox, zone.serial, zone.refresh, zone.retry,
|
||||
zone.expire, zone.minimum, zone.ttl, zone.timestamp);
|
||||
}
|
||||
|
||||
if (bindfile) {
|
||||
fprintf(bindfile, "; Automatically generated by ldap2dns - DO NOT EDIT!\n");
|
||||
fprintf(bindfile, "%s. IN SOA %s. %s. ", zone.domainname, zone.zonemaster, zone.adminmailbox);
|
||||
fprintf(bindfile, "(\n\t%d\t; Serial\n\t%d\t; Refresh\n\t%d\t; Retry\n\t%d\t; Expire\n\t%d )\t; Minimum\n", zone.serial, zone.refresh, zone.retry, zone.expire, zone.minimum);
|
||||
if (namedmaster) {
|
||||
fprintf(namedmaster, "zone \"%s\" %s {\n\ttype master;\n\tfile \"%s.db\";\n};\n",
|
||||
zone.domainname, zone.class, zone.domainname);
|
||||
}
|
||||
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
byte_zero(zone.timestamp, 8);
|
||||
len = strlen(zone.domainname);
|
||||
if (!dns_domain_fromdot(&dottemp1, zone.domainname, len)) die_exit(0);
|
||||
uint32_pack_big(soa, zone.serial);
|
||||
uint32_pack_big(soa+4, zone.refresh);
|
||||
uint32_pack_big(soa+8, zone.retry);
|
||||
uint32_pack_big(soa+12, zone.expire);
|
||||
uint32_pack_big(soa+16, zone.minimum);
|
||||
rr_start(DNS_T_SOA, zone.ttl, zone.timestamp);
|
||||
if (namedzone) {
|
||||
fprintf(namedzone, "# Automatically generated by ldap2dns - DO NOT EDIT!\n");
|
||||
fprintf(namedzone, "$TTL %d\n", (zone.ttl>0) ? zone.ttl : 3600);
|
||||
fprintf(namedzone, "%s. IN SOA ", zone.domainname);
|
||||
len = strlen(zone.zonemaster);
|
||||
if (!dns_domain_fromdot(&dottemp2, zone.zonemaster, len)) die_exit(0);
|
||||
rr_addname(dottemp2);
|
||||
fprintf(namedzone, (zone.zonemaster[len-1]=='.') ? "%s " : "%s. ", zone.zonemaster);
|
||||
len = strlen(zone.adminmailbox);
|
||||
if (!dns_domain_fromdot(&dottemp2, zone.adminmailbox, len)) die_exit(0);
|
||||
rr_addname(dottemp2);
|
||||
rr_add(soa, 20);
|
||||
rr_finish(dottemp1);
|
||||
fprintf(namedzone, (zone.adminmailbox[len-1]=='.') ? "%s " : "%s. ", zone.adminmailbox);
|
||||
fprintf(namedzone, "(\n\t%d\t; Serial\n\t%d\t; Refresh\n\t%d\t; Retry\n\t%d\t; Expire\n\t%d )\t; Minimum\n", zone.serial, zone.refresh, zone.retry, zone.expire, zone.minimum);
|
||||
}
|
||||
#endif
|
||||
if (options.ldifname[0])
|
||||
fprintf(ldifout, "\n");
|
||||
}
|
||||
@@ -725,6 +629,8 @@ static void read_dnszones(void)
|
||||
|
||||
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)) {
|
||||
@@ -735,6 +641,7 @@ static void read_dnszones(void)
|
||||
char zdn[256][64];
|
||||
char ldif0;
|
||||
|
||||
strncpy(zone.class, "IN", 3);
|
||||
zone.serial = time_now;
|
||||
zone.refresh = 10800;
|
||||
zone.retry = 3600;
|
||||
@@ -812,16 +719,16 @@ static void read_dnszones(void)
|
||||
options.ldifname[0] = '\0';
|
||||
if (options.verbose&1)
|
||||
printf("zonename: %s\n", zone.domainname);
|
||||
if (options.output&4) {
|
||||
char bindfilename[128];
|
||||
sprintf(bindfilename, "%s.db", zone.domainname);
|
||||
if ( !(bindfile = fopen(bindfilename, "w")) )
|
||||
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);
|
||||
if (bindfile)
|
||||
fclose(bindfile);
|
||||
read_resourcerecords(dn, i);
|
||||
if (namedzone)
|
||||
fclose(namedzone);
|
||||
if (options.verbose&2)
|
||||
printf("\n");
|
||||
if (options.ldifname[0])
|
||||
@@ -852,11 +759,12 @@ int main(int argc, char** argv)
|
||||
set_datadir();
|
||||
for (;;) {
|
||||
int ldaperr;
|
||||
if ( !(ldap_con = ldap_init(options.hostname, options.port)) )
|
||||
die_exit("Unable to initialize connection to LDAP server");
|
||||
ldaperr = ldap_simple_bind_s(ldap_con, options.binddn, options.password);
|
||||
ldap_con = ldap_init(options.hostname, options.port);
|
||||
ldaperr = ldap_con && ldap_simple_bind_s(ldap_con, options.binddn, options.password);
|
||||
if (ldaperr!=LDAP_SUCCESS) {
|
||||
fprintf(stderr, "Warning - Could not connect to LDAP server %s:%d as '%s'\n", options.hostname, options.port, options.binddn);
|
||||
if (options.is_daemon==0)
|
||||
break;
|
||||
sleep(options.update_iv);
|
||||
continue;
|
||||
}
|
||||
@@ -872,13 +780,6 @@ int main(int argc, char** argv)
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
fdcdb = open_trunc(tinydns_tempfile);
|
||||
if (fdcdb == -1) die_exit("Unable to create 'data.tmp'");
|
||||
if (cdb_make_start(&cdb, fdcdb) == -1) die_exit("Unable to create 'data.tmp'");
|
||||
}
|
||||
#endif
|
||||
if (options.ldifname[0]) {
|
||||
if (options.ldifname[0]=='-')
|
||||
ldifout = stdout;
|
||||
@@ -888,21 +789,24 @@ int main(int argc, char** argv)
|
||||
die_exit("Unable to open LDIF-file for writing");
|
||||
}
|
||||
time(&time_now);
|
||||
if ( options.output&2 && !(tinyfile = fopen(tinydns_textfile, "w")) )
|
||||
die_exit("Unable to open file 'data' for writing");
|
||||
if ( options.output&OUTPUT_DATA && !(tinyfile = fopen(tinydns_texttemp, "w")) )
|
||||
die_exit("Unable to open file 'data.temp' for writing");
|
||||
if ( options.output&OUTPUT_DB && !(namedmaster = fopen("named.zones", "w")) )
|
||||
die_exit("Unable to open file 'named.zones' for writing");
|
||||
read_dnszones();
|
||||
if (tinyfile)
|
||||
if (namedmaster)
|
||||
fclose(namedmaster);
|
||||
if (tinyfile) {
|
||||
fclose(tinyfile);
|
||||
if (soa_numzones==0 || soa_checksum==0)
|
||||
break;
|
||||
if (rename(tinydns_texttemp, tinydns_textfile)==-1)
|
||||
die_exit("Unable to move 'data.temp' to 'data'");
|
||||
}
|
||||
if (options.ldifname[0] && ldifout)
|
||||
fclose(ldifout);
|
||||
#if defined WITH_TINYDNS
|
||||
if (options.output&1) {
|
||||
if (cdb_make_finish(&cdb)==-1 || fsync(fdcdb)==-1 || close(fdcdb)==-1)
|
||||
die_exit("Unable to create 'data.tmp'");
|
||||
if (rename(tinydns_tempfile, tinydns_datafile)==-1)
|
||||
die_exit("Unable to move 'data.tmp' to 'data.cdb'");
|
||||
}
|
||||
#endif
|
||||
if (options.exec_command[0])
|
||||
system(options.exec_command);
|
||||
skip:
|
||||
if ( (ldaperr = ldap_unbind_s(ldap_con))!=LDAP_SUCCESS )
|
||||
die_ldap(ldaperr);
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
#!/bin/sh
|
||||
mkdir ldap2tinydns
|
||||
mkdir ldap2tinydns/env
|
||||
echo "#!/bin/sh" > ldap2tinydns/run
|
||||
echo "exec 2>&1" >> ldap2tinydns/run
|
||||
echo "exec envdir ./env softlimit -d250000 /usr/bin/ldap2dns -u 59" >> ldap2tinydns/run
|
||||
cat << EOF_run > 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 755 ldap2tinydns/run
|
||||
echo "/var/tinydns/root" > ldap2tinydns/env/TINYDNSDIR
|
||||
echo "30" > ldap2tinydns/env/LDAP2DNS_UPDATE
|
||||
echo "DATA" > ldap2tinydns/env/LDAP2DNS_OUTPUT
|
||||
|
||||
|
||||
509
zoneedit.pl
Normal file
509
zoneedit.pl
Normal file
@@ -0,0 +1,509 @@
|
||||
#!/usr/sbin/perl
|
||||
use CGI qw(:standard);
|
||||
use Net::LDAP;
|
||||
use strict;
|
||||
use vars qw($LDAPHOST $BASEDN $BINDBASE $BINDUID $ANONBINDDN $ZONEEDIT $DEFAULT_MAIN @our_nameserver @zoneinfo @setinfo);
|
||||
my $LDAPHOST = "ldap0.server";
|
||||
my $BASEDN = "ou=dns,o=tiscover";
|
||||
my $BINDBASE = "ou=people,o=tiscover";
|
||||
my $BINDUID = "uid";
|
||||
my $ANONBINDDN = "ou=dns,o=tiscover";
|
||||
my $ZONEEDIT = "zoneedit.pl";
|
||||
my $DEFAULT_MAIN = "index.html";
|
||||
my $LOGFILE = "/opt/httpd/logs/zoneedit.log";
|
||||
my @our_nameserver = ( "ns1.tis.co.at", "ns2.tis.co.at" );
|
||||
my @zoneinfo = qw( DNSzonename DNSserial DNSclass DNStype DNSexpire DNSretry DNSminimum DNSzonemaster DNSrefresh DNSadminmailbox DNSttl );
|
||||
my @setinfo = qw( DNSdomainname DNStype DNSclass DNScname DNSipaddr DNSttl );
|
||||
|
||||
|
||||
################################################################################
|
||||
|
||||
eval {
|
||||
main();
|
||||
};
|
||||
if ($@) {
|
||||
errconfirm($@);
|
||||
}
|
||||
|
||||
|
||||
sub main
|
||||
{
|
||||
my $request = Apache->request();
|
||||
my $query = new CGI;
|
||||
my $call = $query->param('call');
|
||||
if (defined $call) {
|
||||
my $ldap = Net::LDAP->new($LDAPHOST) or die "can't make new LDAP object: $@";
|
||||
my $user = $request->connection->user();
|
||||
my $binddn = $BINDUID."=".$user.",$BINDBASE";
|
||||
my ($ret, $password) = $request->get_basic_auth_pw();
|
||||
my $mesg = $ldap->bind($binddn, password => $password);
|
||||
die "Unable to bind to LDAP server.<BR>Reason: ".$mesg->error if ($mesg->code);
|
||||
my $selet = $query->param('selet') if $query->param('selet');
|
||||
if ($call eq "dnslist") {
|
||||
dns_list($query, $ldap, $selet);
|
||||
} elsif ($call eq "newzone") {
|
||||
new_zone($query, $selet);
|
||||
} elsif ($call eq "addzone") {
|
||||
my $zonedn = add_zone($query, $ldap);
|
||||
log_action($user, "add_zone", $zonedn);
|
||||
$query->delete_all();
|
||||
print $query->header, $query->start_html(-title=> 'Edit DNS Zone',
|
||||
-target=> 'main',
|
||||
-author=> 'jacob.rief@tiscover.com',
|
||||
-BGCOLOR=> 'WHITE'),
|
||||
"<CENTER><BR>";
|
||||
edit_zone($query, $ldap, $zonedn, $selet);
|
||||
print $query->end_html;
|
||||
} elsif ($call eq "editzone") {
|
||||
my $zonedn = $query->param('zonedn');
|
||||
if (defined $query->param('modifyzone')) {
|
||||
modify_zone($query, $ldap, $zonedn);
|
||||
log_action($user, "modify_zone_soa", $zonedn);
|
||||
} elsif (defined $query->param('addrrset')) {
|
||||
add_rrset($query, $ldap, $zonedn);
|
||||
log_action($user, "add_rrset", $zonedn);
|
||||
} elsif (defined $query->param('modifyrrset')) {
|
||||
my $setdn = $query->param('setdn');
|
||||
modify_rrset($query, $ldap, $zonedn, $setdn);
|
||||
log_action($user, "modify_rrset", $setdn);
|
||||
} elsif (defined $query->param('deleterrset')) {
|
||||
my $setdn = $query->param('setdn');
|
||||
delete_rrset($query, $ldap, $zonedn, $setdn);
|
||||
log_action($user, "delete_rrset", $setdn);
|
||||
}
|
||||
$query->delete_all();
|
||||
print $query->header, $query->start_html(-title=> 'Edit DNS Zone',
|
||||
-target=> 'main',
|
||||
-author=> 'jacob.rief@tiscover.com',
|
||||
-BGCOLOR=> 'WHITE'),
|
||||
"<CENTER><BR>";
|
||||
print_whois($ldap, $zonedn) if ($request->method eq "GET");
|
||||
edit_zone($query, $ldap, $zonedn, $selet);
|
||||
print $query->end_html;
|
||||
} elsif ($call eq "deletezone") {
|
||||
my $zonedn = $query->param('zonedn');
|
||||
delete_zone($query, $ldap, $zonedn);
|
||||
log_action($user, "delete_zone", $zonedn);
|
||||
}
|
||||
$ldap->unbind();
|
||||
} else {
|
||||
# print frame
|
||||
print $query->header,
|
||||
"<FRAMESET COLS=\"250,*\" BORDER=0 FRAMEBORDER=0 FRAMESPACING=0>",
|
||||
" <FRAME SRC=\"$ZONEEDIT?call=dnslist&nslu=1\" NAME=\"menu\" NORESIZE MARGINWIDTH=0 MARGINHEIGHT=0>",
|
||||
" <FRAME SRC=\"$DEFAULT_MAIN\" NAME=\"main\" MARGINWIDTH=0 MARGINHEIGHT=0>",
|
||||
"</FRAMESET>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub errconfirm
|
||||
{
|
||||
my $errmsg = shift;
|
||||
my $request = Apache->request();
|
||||
$request->note_basic_auth_failure();
|
||||
my $query = new CGI;
|
||||
print $query->header, $query->start_html(-title=> 'DNS Zone Admin',
|
||||
-target=> 'main',
|
||||
-author=> 'jacob.rief@tiscover.com',
|
||||
-BGCOLOR=> 'WHITE'),
|
||||
"<CENTER><BR>",
|
||||
$query->h2("An error occured"),
|
||||
"<FONT color=red>Message: $errmsg</FONT><BR>\n",
|
||||
$query->end_html;
|
||||
$request->child_terminate();
|
||||
}
|
||||
|
||||
|
||||
sub log_action
|
||||
{
|
||||
my ($user, $action, $dn) = @_;
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime();
|
||||
my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec);
|
||||
my ($m, $y) = ($month[$mon], $year+1900);
|
||||
open(FILE, ">>$LOGFILE");
|
||||
print FILE "[$mday/$m/$y:$hour:$min:$sec] $user $action $dn\n";
|
||||
close(FILE);
|
||||
}
|
||||
|
||||
|
||||
sub list_attrs
|
||||
{
|
||||
my $attr = shift;
|
||||
my (@list, $key, $value);
|
||||
while (($key, $value) = each %$attr) {
|
||||
push(@list, $key => $value);
|
||||
}
|
||||
return \@list;
|
||||
}
|
||||
|
||||
|
||||
sub dns_list
|
||||
{
|
||||
my ($query, $ldap, $selet) = @_;
|
||||
my @letters = qw( 0 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z );
|
||||
print $query->header, $query->start_html(-title=> 'Zone-Selector',
|
||||
-target=> 'menu',
|
||||
-author=> 'jacob.rief@tiscover.com',
|
||||
-BGCOLOR=> 'WHITE');
|
||||
my ($dnslookup, $resolver);
|
||||
if ($selet =~ /\~/) {
|
||||
$dnslookup = 1;
|
||||
use Net::DNS;
|
||||
$resolver = new Net::DNS::Resolver;
|
||||
} else {
|
||||
$dnslookup = 0;
|
||||
}
|
||||
print "<TABLE BORDER=0 CELLSPACING=1 CELLPADDING=1 COLS=1 BGCOLOR=#BBBBBB>\n",
|
||||
"<TR ALIGN=center><TH><A HREF=\"$ZONEEDIT?call=newzone&selet=$selet\" TARGET=\"main\">Add New Zone</A></TH></TR>\n";
|
||||
foreach my $let (@letters) {
|
||||
if ($selet =~ /$let/) {
|
||||
my $newselet = $selet;
|
||||
$newselet =~ s/$let//;
|
||||
print "<TR><TD><A HREF=\"$ZONEEDIT?call=dnslist&selet=$newselet\"><B>- $let</B></A></TD></TR>\n";
|
||||
} else {
|
||||
my $newselet = $selet.$let;
|
||||
print "<TR><TD><A HREF=\"$ZONEEDIT?call=dnslist&selet=$newselet\"><B>+ $let</B></A></TD></TR>\n";
|
||||
next;
|
||||
}
|
||||
my $mesg = $ldap->search(base => $BASEDN, filter => "(&(objectclass=DNSzone)(DNSzonename=$let*))");
|
||||
my @entries = $mesg->entries;
|
||||
my ($zonename, %dn_entry, @unsorted);
|
||||
foreach my $entry (@entries) {
|
||||
$zonename = $entry->get_value('DNSzonename');
|
||||
push @unsorted, $zonename;
|
||||
$dn_entry{$zonename} = $entry->dn();
|
||||
}
|
||||
@entries = sort @unsorted;
|
||||
foreach $zonename (@entries) {
|
||||
my $zonedn = $dn_entry{$zonename};
|
||||
if ($dnslookup) {
|
||||
my $query = $resolver->search($zonename, "NS");
|
||||
my @ns;
|
||||
if ($query) {
|
||||
foreach my $rr ($query->answer) {
|
||||
next unless $rr->type eq "NS";
|
||||
push @ns, $rr->nsdname;
|
||||
}
|
||||
}
|
||||
if (lc($ns[0]) eq lc($our_nameserver[0]) || lc($ns[1]) eq lc($our_nameserver[1])
|
||||
|| lc($ns[0]) eq lc($our_nameserver[1]) || lc($ns[1]) eq lc($our_nameserver[0]) ) {
|
||||
print "<TR ALIGN=center BGCOLOR=#AAFFAA><TD>";
|
||||
} elsif (defined $ns[0] || defined $ns[1]) {
|
||||
print "<TR ALIGN=center BGCOLOR=#FFAAAA><TD>";
|
||||
} else {
|
||||
print "<TR ALIGN=center BGCOLOR=#FFFFAA><TD>";
|
||||
}
|
||||
} else {
|
||||
print "<TR ALIGN=center BGCOLOR=#EEEEEE><TD>";
|
||||
}
|
||||
print "<A HREF=\"$ZONEEDIT?call=editzone&zonedn=$zonedn&selet=$selet\" TARGET=\"main\">$zonename</A></TD></TR>\n";
|
||||
}
|
||||
}
|
||||
print "<TR ALIGN=center><TH><A HREF=\"$ZONEEDIT?call=dnslist";
|
||||
if ($dnslookup) {
|
||||
$selet =~ s/\~//;
|
||||
print "&selet=$selet\" TARGET=\"menu\">Without DNS-lookup</A></TH></TR>\n";
|
||||
} else {
|
||||
print "&selet=$selet~\" TARGET=\"menu\">With DNS-lookup</A></TH></TR>\n";
|
||||
}
|
||||
print "</TABLE>\n", $query->end_html;
|
||||
}
|
||||
|
||||
|
||||
sub print_zone_soa
|
||||
{
|
||||
my $zonedata = shift;
|
||||
print "<TR><TD ALIGN=right>Serial: </TD><TD>",
|
||||
textfield(-name=>'DNSserial', -size=>16, -maxlength=>24, -default=>$$zonedata{'DNSserial'}),
|
||||
"</TD>", "<TD ALIGN=right>Refresh: </TD><TD>",
|
||||
textfield(-name=>'DNSrefresh', -size=>16, -maxlength=>24, -default=>$$zonedata{'DNSrefresh'}),
|
||||
"</TD></TR>\n",
|
||||
|
||||
"<TR><TD ALIGN=right>Retry: </TD><TD>",
|
||||
textfield(-name=>'DNSretry', -size=>16, -maxlength=>24, -default=>$$zonedata{'DNSretry'}),
|
||||
"</TD>", "<TD ALIGN=right>Expire: </TD><TD>",
|
||||
textfield(-name=>'DNSexpire', -size=>16, -maxlength=>24, -default=>$$zonedata{'DNSexpire'}),
|
||||
"</TD></TR>\n",
|
||||
|
||||
"<TR><TD ALIGN=right>Minimum: </TD><TD>",
|
||||
textfield(-name=>'DNSminimum', -size=>16, -maxlength=>24, -default=>$$zonedata{'DNSminimum'}),
|
||||
"</TD>", "<TD ALIGN=right>Adminmailbox: </TD><TD>",
|
||||
textfield(-name=>'DNSadminmailbox', -size=>16, -maxlength=>24, -default=>$$zonedata{'DNSadminmailbox'}),
|
||||
"</TD></TR>\n",
|
||||
|
||||
"<TR><TD ALIGN=right>Zonemaster: </TD><TD>",
|
||||
textfield(-name=>'DNSzonemaster', -size=>16, -maxlength=>24, -default=>$$zonedata{'DNSzonemaster'}),
|
||||
"</TD>", "<TD ALIGN=right>Time to live: </TD><TD>",
|
||||
textfield(-name=>'DNSttl', -size=>16, -maxlength=>24, -default=>$$zonedata{'DNSttl'}),
|
||||
"</TD><TR>\n";
|
||||
}
|
||||
|
||||
|
||||
sub new_zone
|
||||
{
|
||||
my ($query, $selet) = @_;
|
||||
my %default_zonedata = (
|
||||
"DNSzonename" => "",
|
||||
"DNSserial" => "",
|
||||
"DNSclass" => "IN",
|
||||
"DNStype" => "SOA",
|
||||
"DNSexpire" => "259200",
|
||||
"DNSretry" => "3600",
|
||||
"DNSminimum" => "86400",
|
||||
"DNSzonemaster" => "ns1.tis.co.at.",
|
||||
"DNSrefresh" => "10800",
|
||||
"DNSadminmailbox" => "domreg.tis.co.at.",
|
||||
"DNSttl" => "3600",
|
||||
);
|
||||
my ($sec,$min,$hour,$mday,$mon,$year) = localtime();
|
||||
$default_zonedata{"DNSserial"} = sprintf "%04d%02d%02d01", $year+1900, $mon+1, $mday;
|
||||
my $onsubmit = "{ parent.frames.menu.location='$ZONEEDIT?call=dnslist&selet=$selet'; }";
|
||||
$query->param(call=>'addzone');
|
||||
print $query->header, $query->start_html(-title=> 'Add DNS Zone',
|
||||
-target=> 'main',
|
||||
-author=> 'jacob.rief@tiscover.com',
|
||||
-BGCOLOR=> 'WHITE'),
|
||||
"<CENTER><BR>",
|
||||
$query->h2('Add DNS zone'),
|
||||
$query->start_multipart_form(-method=>'POST', -action=>"$ZONEEDIT", -target=>'main', -onSubmit=>$onsubmit),
|
||||
$query->hidden('call'), $query->hidden('selet'),
|
||||
"<TABLE BORDER=1 WIDTH=85% COLS=4>\n",
|
||||
"<TR><TD ALIGN=right colspan=2> New Zonename: </TD><TD colspan=2>",
|
||||
$query->textfield(-name=>'DNSzonename', -size=>40, -maxlength=>64),
|
||||
"</TD></TR>\n";
|
||||
print_zone_soa(\%default_zonedata);
|
||||
print "<TR><TD colspan=2 ALIGN=center>",
|
||||
$query->submit(-name=>" Submit "),
|
||||
"</TD><TD colspan=2 ALIGN=center>",
|
||||
$query->reset(),
|
||||
"</TD></TR></TABLE>\n",
|
||||
$query->end_form(),
|
||||
$query->end_html;
|
||||
}
|
||||
|
||||
|
||||
sub add_zone
|
||||
{
|
||||
my ($query, $ldap) = @_;
|
||||
my %zonedata;
|
||||
foreach my $za (@zoneinfo) {
|
||||
$zonedata{$za} = $query->param($za) if defined $query->param($za);
|
||||
}
|
||||
my ($zonename, $zonedn) = ($zonedata{'DNSzonename'}, "cn=$zonedata{'DNSzonename'},$BASEDN");
|
||||
my $attrs = list_attrs(\%zonedata);
|
||||
push(@$attrs, "objectclass", "DNSzone", "cn", "$zonename");
|
||||
my $mesg = $ldap->add(dn=>$zonedn, attr=>$attrs);
|
||||
die "Failed to add zone: $zonename<BR>Reason: ".$mesg->error if ($mesg->code);
|
||||
my @attr = ( "cn", "NS1:", "objectclass", "DNSrrset", "dnstype", "NS", "dnsclass", "IN",
|
||||
"dnsttl", "3600", "dnscname", $our_nameserver[0]."." );
|
||||
my $dnch = "cn=NS1:,$zonedn";
|
||||
die "Failed to add $dnch " if (($mesg = $ldap->add(dn=>$dnch, attr=>\@attr))->code);
|
||||
|
||||
@attr = ( "cn", "NS2:", "objectclass", "DNSrrset", "dnstype", "NS", "dnsclass", "IN",
|
||||
"dnsttl", "3600", "dnscname", $our_nameserver[1]."." );
|
||||
$dnch = "cn=NS2:,$zonedn";
|
||||
die "Failed to add $dnch " if (($mesg = $ldap->add(dn=>$dnch, attr=>\@attr))->code);
|
||||
|
||||
@attr = ( "cn", "A:www", "objectclass", "DNSrrset", "dnstype", "A", "dnsclass", "IN",
|
||||
"dnsdomainname", "www", "dnsttl", "3600", "dnsipaddr", "195.96.23.204" );
|
||||
$dnch = "cn=A:www,$zonedn";
|
||||
die "Failed to add $dnch<BR>Reason: ".$mesg->error if (($mesg = $ldap->add(dn=>$dnch, attr=>\@attr))->code);
|
||||
return $zonedn;
|
||||
}
|
||||
|
||||
|
||||
sub modify_zone
|
||||
{
|
||||
my ($query, $ldap, $zonedn) = @_;
|
||||
my %zonedata;
|
||||
foreach my $za (@zoneinfo) {
|
||||
$zonedata{$za} = $query->param($za) if defined $query->param($za);
|
||||
}
|
||||
my @zonename;
|
||||
my $zn = ($ldap->search(base=>$zonedn, scope=>'base', filter=>"(objectclass=DNSzone)")->entry(0))->get_value('DNSzonename');
|
||||
push @zonename, $zn;
|
||||
for (my $zc = 0; defined $query->param("DNSzonename$zc"); $zc++) {
|
||||
$zn = $query->param("DNSzonename$zc");
|
||||
push @zonename, $zn if (length($zn)>3);
|
||||
}
|
||||
my $mesg = $ldap->modify($zonedn, delete => [ 'DNSzonename' ]);
|
||||
$mesg = $ldap->modify($zonedn, replace => \%zonedata) unless ($mesg->code);
|
||||
$mesg = $ldap->modify($zonedn, add => [ 'DNSzonename' => \@zonename ] ) unless ($mesg->code);
|
||||
die "Unable to modify zone: $zonedn<BR>Reason: ".$mesg->error if ($mesg->code);
|
||||
}
|
||||
|
||||
|
||||
sub delete_zone
|
||||
{
|
||||
my ($query, $ldap, $zonedn) = @_;
|
||||
my $zonedn = $query->param('zonedn');
|
||||
my $mesg = $ldap->search(base=>$zonedn, filter => "(objectclass=DNSrrset)");
|
||||
my @entries = $mesg->entries;
|
||||
foreach my $entry (@entries) {
|
||||
$mesg = $ldap->delete($entry->dn());
|
||||
last if ($mesg->code);
|
||||
}
|
||||
$mesg = $ldap->delete($zonedn) unless ($mesg->code);
|
||||
die "Unable to delete zone $zonedn.<BR>Reason: ".$mesg->error if ($mesg->code);
|
||||
dnslist($query, $ldap);
|
||||
}
|
||||
|
||||
|
||||
sub edit_zone
|
||||
{
|
||||
my ($query, $ldap, $zonedn, $selet) = @_;
|
||||
my @zonename = ($ldap->search(base=>$zonedn, scope=>'base', filter=>"(objectclass=DNSzone)")->entry(0))->get_value('DNSzonename');
|
||||
my $zonemaster = shift @zonename;
|
||||
$query->param(call=>'editzone');
|
||||
$query->param(zonedn=>$zonedn);
|
||||
$query->param(selet=>$selet);
|
||||
|
||||
# Table for SOA
|
||||
print $query->h2("Edit DNS zone <I>$zonemaster</I>");
|
||||
print $query->start_multipart_form(-method=>'POST', -action=>"$ZONEEDIT", -target=>'main'),
|
||||
$query->hidden('call'), $query->hidden('zonedn'), $query->hidden('selet'),
|
||||
"<TABLE BORDER=1 WIDTH=85% COLS=4>\n";
|
||||
my $zc = 0;
|
||||
my $entry = $ldap->search(base=>$zonedn, scope=>'base', filter=>"(objectclass=DNSzone)")->entry(0);
|
||||
my %zonedata;
|
||||
foreach my $za (@zoneinfo) {
|
||||
$zonedata{$za} = $entry->get_value($za);
|
||||
}
|
||||
print_zone_soa(\%zonedata);
|
||||
print "</TD></TR>\n";
|
||||
foreach my $zn (@zonename) {
|
||||
print "<TR><TD ALIGN=right colspan=2> Additional Zonename: </TD><TD colspan=2>",
|
||||
$query->textfield(-name=>"DNSzonename$zc", -default=>$zn, -size=>40, -maxlength=>64),
|
||||
"</TD></TR>\n";
|
||||
$zc++;
|
||||
}
|
||||
print "<TR><TD ALIGN=right colspan=2> Add additional Zonename: </TD><TD colspan=2>",
|
||||
$query->textfield(-name=>"DNSzonename$zc", -size=>40, -maxlength=>64),
|
||||
"</TABLE></TD></TR>\n";
|
||||
print "<TABLE BORDER=1 WIDTH=66% COLS=3><TR><TD align=center>",
|
||||
$query->submit(-name=>"modifyzone", -value=>" Modify Zone "),
|
||||
"</TD><TD align=center>";
|
||||
my $onclick = "if(confirm('Do you really want to remove zone \"$zonemaster\" and all its resource records?'))"
|
||||
."{ parent.frames.menu.location='$ZONEEDIT?call=deletezone&zonedn=$zonedn&selet=$selet'; parent.frames.main.location='$DEFAULT_MAIN'; }";
|
||||
print $query->submit(-name=>"deletezone", -value=>" Delete Zone ", -onClick=>$onclick),
|
||||
"</TD>\n", $query->end_form(),
|
||||
"<TD align=center>", $query->start_multipart_form(-method=>'POST', -action=>"$ZONEEDIT", -target=>'main'),
|
||||
$query->hidden('call'), $query->hidden('zonedn'), $query->hidden('selet'),
|
||||
$query->submit(-name=>"resetform", -value=>" Reset Form "),
|
||||
$query->end_form(), "</TD></TR></TABLE>\n";
|
||||
|
||||
# Tables for RRsets
|
||||
my $mesg = $ldap->search(base=>$zonedn, filter => "(objectclass=DNSrrset)");
|
||||
my @entries = $mesg->entries;
|
||||
print "\n<TABLE BORDER=1 WIDTH=98% COLS=6 CELLSPACING=0 CELLPADDING=1>\n",
|
||||
"<TR><TH width=20>Name $#entries</TH><TH width=15>Type</TH><TH width=40>IPaddr</TH><TH width=40>CNAME</TH><TH width=20>TTL</TH><TH></TH></TR>\n";
|
||||
foreach $entry (@entries) {
|
||||
my $setdn = $entry->dn();
|
||||
my $domainname = $entry->get_value('DNSdomainname');
|
||||
$domainname = "." if (!defined $domainname || length($domainname)<1);
|
||||
my $ipaddr = $entry->get_value('DNSipaddr');
|
||||
my $cname = $entry->get_value('DNScname');
|
||||
my $type = $entry->get_value('DNStype');
|
||||
my $ttl = $entry->get_value('DNSttl');
|
||||
$query->param(setdn => $setdn);
|
||||
print "<TR align=center>", $query->start_multipart_form(-method=>'POST', -action=>"$ZONEEDIT", -target=>'main'), $query->hidden('call'),
|
||||
$query->hidden('selet'), $query->hidden('zonedn'), $query->hidden('setdn'),
|
||||
"<TD><B>$domainname</B></TD>",
|
||||
"<TD><B>$type</B></TD>",
|
||||
"<TD>", $query->textfield(-name=>'DNSipaddr', -default=>$ipaddr, -size=>16, -maxlength=>16), "</TD>",
|
||||
"<TD>", $query->textfield(-name=>'DNScname', -default=>$cname, -size=>16, -maxlength=>64), "</TD>",
|
||||
"<TD>", $query->textfield(-name=>'DNSttl', -default=>$ttl, -size=>6, -maxlength=>6), "</TD>",
|
||||
"<TD>", $query->submit(-name=>"modifyrrset", -value=>" Modify "),
|
||||
$query->submit(-name=>"deleterrset", -value=>" Delete "), "</TD>",
|
||||
$query->end_form(), "</TR>\n";
|
||||
}
|
||||
print "\n<TR align=center>", $query->start_multipart_form(-method=>'POST', -action=>"$ZONEEDIT", -target=>'main'), $query->hidden('call'),
|
||||
$query->hidden('selet'), $query->hidden('zonedn'),
|
||||
"<TD>", textfield(-name=>'DNSdomainname', -size=>8, -maxlength=>32), "</TD>",
|
||||
"<TD>", $query->popup_menu(-name=>'DNStype', -values=>['CNAME','A','MX','NS','PTR','TXT'], -default=>"A"), "</TD>",
|
||||
"<TD>", textfield(-name=>'DNSipaddr', -size=>16, -maxlength=>16), "</TD>",
|
||||
"<TD>", textfield(-name=>'DNScname', -size=>16, -maxlength=>64), "</TD>",
|
||||
"<TD>", textfield(-name=>'DNSttl', -default=>"3600", -size=>6, -maxlength=>6), "</TD>",
|
||||
"<TD>", $query->submit(-name=>"addrrset", -value=>" Add "), "</TD>",
|
||||
$query->end_form();
|
||||
print "</TR></TABLE>\n";
|
||||
}
|
||||
|
||||
|
||||
sub add_rrset
|
||||
{
|
||||
my ($query, $ldap, $zonedn) = @_;
|
||||
my ($domainname, $type, @setattrs) = ($query->param('DNSdomainname'), $query->param('DNStype'));
|
||||
foreach my $za (@setinfo) {
|
||||
next unless (defined $query->param($za));
|
||||
push (@setattrs, $za, $query->param($za));
|
||||
}
|
||||
my $chdn = "$type:$domainname";
|
||||
push (@setattrs, "objectclass", "DNSrrset", "cn", "$chdn");
|
||||
$chdn = "cn=$chdn,$zonedn";
|
||||
my $mesg = $ldap->add($chdn, attr => \@setattrs);
|
||||
die "Unable to add rrset: $chdn ".$mesg->error if ($mesg->code);
|
||||
my $newserial = $ldap->search(base=>$zonedn, scope=>'base', filter => "(objectclass=DNSzone)")->entry(0)->get_value('DNSserial')+1;
|
||||
$mesg = $ldap->modify($zonedn, replace => { 'DNSserial', $newserial });
|
||||
die "Unable to modify serial number for: $zonedn ".$mesg->error if ($mesg->code);
|
||||
}
|
||||
|
||||
|
||||
sub modify_rrset
|
||||
{
|
||||
my ($query, $ldap, $zonedn, $setdn) = @_;
|
||||
my %setattrs;
|
||||
foreach my $za (@setinfo) {
|
||||
next unless (defined $query->param($za));
|
||||
$setattrs{$za} = $query->param($za);
|
||||
}
|
||||
my $mesg = $ldap->modify($setdn, replace => \%setattrs);
|
||||
die "Unable to modify rrset: $setdn".$mesg->error if ($mesg->code);
|
||||
my $newserial = $ldap->search(base=>$zonedn, scope=>'base', filter => "(objectclass=DNSzone)")->entry(0)->get_value('DNSserial')+1;
|
||||
$mesg = $ldap->modify($zonedn, replace => { 'DNSserial', $newserial });
|
||||
die "Unable to modify serial number for: $zonedn ".$mesg->error if ($mesg->code);
|
||||
}
|
||||
|
||||
|
||||
sub delete_rrset
|
||||
{
|
||||
my ($query, $ldap, $zonedn, $setdn) = @_;
|
||||
my $mesg = $ldap->delete($setdn);
|
||||
die "Unable to modify rrset: $setdn".$mesg->error if ($mesg->code);
|
||||
my $newserial = $ldap->search(base=>$zonedn, scope=>'base', filter => "(objectclass=DNSzone)")->entry(0)->get_value('DNSserial')+1;
|
||||
$mesg = $ldap->modify($zonedn, replace => { 'DNSserial', $newserial });
|
||||
die "Unable to modify serial number for: $zonedn ".$mesg->error if ($mesg->code);
|
||||
}
|
||||
|
||||
|
||||
sub print_whois
|
||||
{
|
||||
my ($ldap, $zonedn) = @_;
|
||||
my ($zonename, $whois) = ($ldap->search(base=>$zonedn, scope=>'base', filter=>"(objectclass=DNSzone)")->entry(0))->get_value('DNSzonename');
|
||||
use Net::Whois;
|
||||
unless ($whois = new Net::Whois::Domain $zonename) {
|
||||
print "<H4>Unable to contact Whois-server</H4>";
|
||||
return;
|
||||
};
|
||||
unless ($whois->ok) {
|
||||
print "<H4>No Whois-record found for zone <I>$zonename</I> trying with ";
|
||||
# try with parent zone
|
||||
if ($zonename =~ /[^.]+\.(.*)/) {
|
||||
$zonename = $1;
|
||||
}
|
||||
print "<I>$zonename</I></H4>\n";
|
||||
$whois = new Net::Whois::Domain($zonename);
|
||||
return unless ($whois->ok);
|
||||
}
|
||||
print "<H3>Whois record for zone <I>$zonename</I></H3>\n";
|
||||
print "Domain: ", $whois->domain, "<BR>\n";
|
||||
print "Name: ", $whois->name, "<BR>\n";
|
||||
print "Tag: ", $whois->tag, "<BR>\n";
|
||||
print "Address:\n", map { " $_<BR>\n" } $whois->address;
|
||||
print "Country: ", $whois->country, "<BR>\n";
|
||||
print "Name Servers:<BR>\n", map { " $$_[0] ($$_[1])<BR>\n" } @{$whois->servers};
|
||||
print "Record created:", $whois->record_created, "<BR>\n";
|
||||
print "Record updated:", $whois->record_updated, "<BR>\n" ;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user