mirror of
https://github.com/bklang/ldap2dns.git
synced 2025-10-27 14:24:15 -04:00
* Ensure all options get initialized to defaults before any attempts at setting
them via configuration, environment, or cmdline args. * Allow all cmdline args to be set optionally using environment variables * Updated documentation and added plaintext version git-svn-id: https://svn.alkaloid.net/gpl/ldap2dns/trunk@386 06cd67b6-e706-0410-b29e-9de616bca6e9
This commit is contained in:
14
ChangeLog
14
ChangeLog
@@ -1,5 +1,11 @@
|
|||||||
# $Id$
|
# $Id$
|
||||||
Version 0.4.1 (latest)
|
Version 0.4.2-beta (latest)
|
||||||
|
* Ensure all options get initialized to defaults before any attempts at setting
|
||||||
|
them via configuration, environment, or cmdline args.
|
||||||
|
* Allow all cmdline args to be set optionally using environment variables
|
||||||
|
* Updated documentation and added plaintext version
|
||||||
|
|
||||||
|
Version 0.4.1 - 2006/10/19
|
||||||
* Updated scripts/data2ldif.pl to properly handle reverse domains
|
* Updated scripts/data2ldif.pl to properly handle reverse domains
|
||||||
* Fixed parser bugs in scripts/data2ldif.pl (Thanks Fleischmann Bonaventura and
|
* Fixed parser bugs in scripts/data2ldif.pl (Thanks Fleischmann Bonaventura and
|
||||||
Adrian Goins)
|
Adrian Goins)
|
||||||
@@ -11,7 +17,7 @@ Version 0.4.1 (latest)
|
|||||||
Gregory for the bug report)
|
Gregory for the bug report)
|
||||||
* Updated FAQ
|
* Updated FAQ
|
||||||
|
|
||||||
Version 0.4.0
|
Version 0.4.0 - 2006/06/17
|
||||||
+ Corrected segfault when using BIND output with SRV records (Thanks Fred Leitz)
|
+ Corrected segfault when using BIND output with SRV records (Thanks Fred Leitz)
|
||||||
+ Fixed off-by-one string termination problem
|
+ Fixed off-by-one string termination problem
|
||||||
+ Fixed a number of possible segfaults if required cmdline options were missing
|
+ Fixed a number of possible segfaults if required cmdline options were missing
|
||||||
@@ -22,7 +28,7 @@ Version 0.4.0
|
|||||||
+ Added search timeout and max record count options
|
+ Added search timeout and max record count options
|
||||||
+ Added warnings when zero records are returned from searches
|
+ Added warnings when zero records are returned from searches
|
||||||
|
|
||||||
Version 0.3.7
|
Version 0.3.7 - Unreleased.
|
||||||
+ Changed default location of ldap.conf to /etc/ldap.conf
|
+ Changed default location of ldap.conf to /etc/ldap.conf
|
||||||
+ Added note on potential security vulns in deprecated/webadmin to README
|
+ Added note on potential security vulns in deprecated/webadmin to README
|
||||||
+ Changed port declarations/format strings from int to unsigned short
|
+ Changed port declarations/format strings from int to unsigned short
|
||||||
@@ -32,7 +38,7 @@ Version 0.3.7
|
|||||||
+ Fixed typo in ldap2dns.spec.in
|
+ Fixed typo in ldap2dns.spec.in
|
||||||
+ Updated example ldif in doc/ (Thanks Marc Huot)
|
+ Updated example ldif in doc/ (Thanks Marc Huot)
|
||||||
|
|
||||||
Version 0.3.6
|
Version 0.3.6 - 2005/12/16
|
||||||
+ New maintainer: Ben Klang <ben@alkaloid.net>
|
+ New maintainer: Ben Klang <ben@alkaloid.net>
|
||||||
+ Fixed bug with duplicate OIDs in dns.schema from partially applied patch
|
+ Fixed bug with duplicate OIDs in dns.schema from partially applied patch
|
||||||
+ Renamed schema file to ldap2dns.schema
|
+ Renamed schema file to ldap2dns.schema
|
||||||
|
|||||||
427
doc/README
Normal file
427
doc/README
Normal file
@@ -0,0 +1,427 @@
|
|||||||
|
LDAP to DNS gateway
|
||||||
|
|
||||||
|
ldap2dns is a program to read DNS (Domain Name Service) records from an LDAP
|
||||||
|
directory and format them into flat files suitable for TinyDNS (or Bind).
|
||||||
|
|
||||||
|
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 modify the data stored in the LDAP directory.
|
||||||
|
|
||||||
|
Optionally access control can be configured for each zone, GUIs can be more
|
||||||
|
easily implemented, and add all other kind of zone and resource record
|
||||||
|
information can be managed 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 zone db files used by named as found in
|
||||||
|
the BIND package.
|
||||||
|
|
||||||
|
ldap2dns is known to compile and run under Linux and Solaris using GCC or Sun
|
||||||
|
Studio C Compiler.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
The two most-widely-used domain name service daemons, named and tinydns are
|
||||||
|
supported.
|
||||||
|
|
||||||
|
ldap2dns specifically 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 (and possibly version 9), 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 the original author implemented
|
||||||
|
a similar object-scheme more suitable for tinydns.
|
||||||
|
|
||||||
|
Installation
|
||||||
|
|
||||||
|
* Install an LDAP server such as openldap. Other LDAP implementations may
|
||||||
|
work but have not been tested. If you are building from source you will
|
||||||
|
need to also install the development libraries and include files. On most
|
||||||
|
package based systems these would be the -devel packages (example:
|
||||||
|
openldap-devel).
|
||||||
|
* Install djbdns or BIND. Configuring the nameserver to automatically start
|
||||||
|
and work in your environment is beyond the scope of this document.
|
||||||
|
* Install ldap2dns
|
||||||
|
From RPM:
|
||||||
|
|
||||||
|
$ sudo rpm -Uhv ldap2dns.rpm
|
||||||
|
|
||||||
|
Replace "ldap2dns.rpm" with the file you have downloaded.
|
||||||
|
Now that you have it installed, skip to Usage to continue.
|
||||||
|
|
||||||
|
To build ldap2dns from source:
|
||||||
|
Unpack the package and build it:
|
||||||
|
|
||||||
|
$ gzcat ldap2dns.tar.gz | tar x
|
||||||
|
$ cd ldap2dns-version
|
||||||
|
$ make
|
||||||
|
$ sudo make install
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Configuration
|
||||||
|
|
||||||
|
* Copy the file ldap2dns.schema into the directory /etc/openldap/schema. Add
|
||||||
|
the following line to Your slapd.conf file:
|
||||||
|
|
||||||
|
include /etc/openldap/schema/ldap2dns.schema
|
||||||
|
|
||||||
|
Now restart your LDAP server.
|
||||||
|
|
||||||
|
Note: If you are running OpenLDAP 2.0 or earlier look for appropriate schema
|
||||||
|
files for your version in the deprecated/ subdirectory. These files are known
|
||||||
|
to work as of ldap2dns 0.3.5 but are no longer supported for future feature
|
||||||
|
updates.
|
||||||
|
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Schema Documentation
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
ATTRIBUTE VALUE Comment
|
||||||
|
objectclass DNSzone required
|
||||||
|
cn common name required
|
||||||
|
DNSzonename Name of the zone required, multivalued
|
||||||
|
DNSserial Serial number of SOA optional
|
||||||
|
DNSrefresh Refresh time of SOA optional, only used for zone
|
||||||
|
transfers
|
||||||
|
DNSretry Retry time of SOA optional, only used for zone
|
||||||
|
transfers
|
||||||
|
DNSexpire Expire time of SOA optional, only used for zone
|
||||||
|
transfers
|
||||||
|
DNSminimum Minimum time to live optional, only used for zone
|
||||||
|
transfers
|
||||||
|
DNSadminmailbox Hostmaster's contact address optional
|
||||||
|
DNSzonemaster Primary nameserver for this optional
|
||||||
|
zone
|
||||||
|
DNStype SOA must be SOA
|
||||||
|
DNSclass IN must be IN
|
||||||
|
DNSttl time to live optional, only used with tinydns
|
||||||
|
DNStimestamp timestamp optional, 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.
|
||||||
|
|
||||||
|
ATTRIBUTE VALUE Comment
|
||||||
|
objectclass DNSrrset required
|
||||||
|
cn common name required
|
||||||
|
DNSdomainname Name of this record optional, relative to zonename
|
||||||
|
DNSipaddr IP address optional, mutivalued
|
||||||
|
DNScname Canonical name optional, without ending dot relative to
|
||||||
|
zonename
|
||||||
|
DNSpreference integer optional, only used for MX records
|
||||||
|
DNStype A, CNAME, NS, MX, PTR must be any valid record type
|
||||||
|
or TXT
|
||||||
|
DNSclass IN must be IN
|
||||||
|
DNSttl time to live optional, only used with tinydns
|
||||||
|
DNStimestamp timestamp optional, only used with tinydns
|
||||||
|
DNSsrvpriority SRV Priority optional, defaults to 0 for SRV records
|
||||||
|
DNSsrvweight SRV Weight optional, defaults to 0 for SRV records
|
||||||
|
DNSsrvport SRV Port Required for SRV records
|
||||||
|
|
||||||
|
|
||||||
|
* 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
|
||||||
|
* DNSsrvpriority: Integer representing the relative priority of this DNS SRV
|
||||||
|
record. See menandmice.com for more information about DNS SRV records.
|
||||||
|
* DNSsrvweight: DNS SRV record weight field. Integer
|
||||||
|
* DNSsrvport: DNS SRV record port number. Integer
|
||||||
|
|
||||||
|
|
||||||
|
Usage: Running ldap2dns
|
||||||
|
|
||||||
|
ldap2dns and ldap2dnsd recognize the following options:
|
||||||
|
|
||||||
|
-D binddn specify the distinguished name to bind to the LDAP directory
|
||||||
|
-w bindpasswd use bindpasswd as password for simple authentication
|
||||||
|
-b searchbase use searchbase as starting point for search instead default
|
||||||
|
-o data 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[filename] print output in LDIF format to [filename] or stdout for reimport
|
||||||
|
-h host specify the hostname of LDAP directory. Default is localhost
|
||||||
|
-p port portnumber to connect to LDAP directory. Defaults is 389
|
||||||
|
-H ldapURI URI for LDAP server (examples: ldap://hostname or ldaps://hostname:636)
|
||||||
|
-v run in verbose mode
|
||||||
|
-vv even more verbose
|
||||||
|
-V print version and exit
|
||||||
|
-u numsecs update DNS data every numsecs.
|
||||||
|
-t timeout timeout for LDAP searches, in seconds
|
||||||
|
-M reclimit Limit LDAP results to reclimit number of records.
|
||||||
|
|
||||||
|
ldap2dns and ldap2dnsd recognize the following environment 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.
|
||||||
|
|
||||||
|
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.conf 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.
|
||||||
|
|
||||||
|
Usage: Running ldap2dnsd
|
||||||
|
|
||||||
|
When ldap2dns is invoked as ldap2dnsd, the program starts as backgound-daemon
|
||||||
|
and continuously 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 and is configurable.
|
||||||
|
The command-line options for ldap2dnsd are the same as for ldap2dns. Use the -u
|
||||||
|
option to modify the update interval. You may also use -u on ldap2dns to start
|
||||||
|
as a foreground daemon. This is useful if You want to run ldap2dns from
|
||||||
|
daemontools.
|
||||||
|
|
||||||
|
These instructions assume you will be running ldap2dns under daemontoolsb> and
|
||||||
|
that tinydns is also running under daemontools. These instructions also assume
|
||||||
|
you are using Dan Bernstein's standard directory locations. Make sure you
|
||||||
|
change the below examples to match your environment.
|
||||||
|
|
||||||
|
Start by creating the a non-root user to run your ldap2dns and associated
|
||||||
|
logging mechanism:
|
||||||
|
|
||||||
|
# groupadd -r ldap2dns
|
||||||
|
# useradd -r -d /dev/null -s /bin/false -c "ldap2dns Daemon" \
|
||||||
|
-g ldap2dns ldap2dns
|
||||||
|
# groupadd -r l2dnslog
|
||||||
|
# useradd -r -d /dev/null -s /bin/false -c "ldap2dns Logger" \
|
||||||
|
-g l2dnslog l2dnslog
|
||||||
|
|
||||||
|
|
||||||
|
Next configure the ldap2dns area to be managed by daemontools. Typically this
|
||||||
|
is /etc/ldap2dns
|
||||||
|
|
||||||
|
# cd /etc
|
||||||
|
# ldap2tinydns-conf ldap2dns l2dnslog /etc/ldap2dns /etc/tinydns/root
|
||||||
|
|
||||||
|
The syntax is close to tinydns-conf except that you will also need to specify
|
||||||
|
the path to the root directory for tinydns. This is the directory that holds
|
||||||
|
the data file.
|
||||||
|
|
||||||
|
Next edit the file /etc/ldap2dns/run and optionally the environment variables
|
||||||
|
in /etc/ldap2dns/env as necessary for your environment. This may include
|
||||||
|
configuring a base DN, a bind DN, a password, and an interval.
|
||||||
|
|
||||||
|
When everything is ready configured properly create a symlink from /etc/
|
||||||
|
ldap2dns into /service. This action will cause daemontools to launch ldap2dns.
|
||||||
|
|
||||||
|
# ln -s /etc/ldap2dns /service/ldap2dns
|
||||||
|
|
||||||
|
After a few seconds daemontools starts ldap2dnsd which itself generates data
|
||||||
|
files whenever a modification is commited into the LDAP directory.
|
||||||
|
|
||||||
|
Importing DNS data from an existing AXFR capable (BIND) name server
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
Importing DNS data from an existing TinyDNS name server
|
||||||
|
|
||||||
|
Use the supplied data2ldap.pl in the scripts/ directory
|
||||||
|
|
||||||
|
$ data2ldap.pl data data.ldif ou=DNS,dc=example,dc=com
|
||||||
|
|
||||||
|
More to come...
|
||||||
|
|
||||||
|
|
||||||
|
Roadmap
|
||||||
|
|
||||||
|
A browser-based administration toolkit, which connects directly to the
|
||||||
|
LDAP-directory service.
|
||||||
|
|
||||||
|
To Do
|
||||||
|
|
||||||
|
* Write a man page.
|
||||||
|
* named.conf should be created automatically.
|
||||||
|
|
||||||
|
Copyright and Disclaimer
|
||||||
|
|
||||||
|
This program is Copyright 1999-2004 Jacob Rief and 2005-2006 Ben Klang
|
||||||
|
This program is licensed under the GPL version 2
|
||||||
|
|
||||||
|
ldap2dns was originally written by Jacob Rief (jacob.rief@tiscover.com). It is
|
||||||
|
now maintained by Ben Klang (bklang@alkaloid.net). If you run ldap2dns on a
|
||||||
|
production nameserver, please send the maintainer an email and mention on what
|
||||||
|
OS and with which nameserver you do so.
|
||||||
|
|
||||||
|
Disclaimer: The author and all contributors disclaim any kind of warranty or
|
||||||
|
liability or suitability for any purpose. By running this software you agree
|
||||||
|
that you are a competent systems administrator and will bear the responsibility
|
||||||
|
for your actions.
|
||||||
|
|
||||||
|
Download
|
||||||
|
|
||||||
|
Latest Release: ldap2dns version 0.4.1
|
||||||
|
|
||||||
|
Released October 19, 2006
|
||||||
|
ChangeLog
|
||||||
|
|
||||||
|
|
||||||
|
Developer Access:
|
||||||
|
|
||||||
|
The bleeding edge of ldap2dns is in the Alkaloid Networks subversion repository
|
||||||
|
found at https://svn.alkaloid.net/gpl/ldap2dns/trunk.
|
||||||
|
|
||||||
|
Following the Subversion standard, releases are kept in /gpl/ldap2dns/tags and
|
||||||
|
branches are in /gpl/ldap2dns/branches.
|
||||||
|
|
||||||
1568
doc/README.html
1568
doc/README.html
File diff suppressed because it is too large
Load Diff
128
ldap2dns.c
128
ldap2dns.c
@@ -234,12 +234,31 @@ static int parse_options()
|
|||||||
int digit_optind = 0;
|
int digit_optind = 0;
|
||||||
FILE* ldap_conf,*fp;
|
FILE* ldap_conf,*fp;
|
||||||
char* ev;
|
char* ev;
|
||||||
|
int tmp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* Initialize the options to their defaults */
|
||||||
|
len = strlen(main_argv[0]);
|
||||||
|
if (strcmp(main_argv[0]+len-9, "ldap2dnsd")==0) {
|
||||||
|
options.is_daemon = 1;
|
||||||
|
options.update_iv = UPDATE_INTERVAL;
|
||||||
|
} else {
|
||||||
|
options.is_daemon = 0;
|
||||||
|
options.update_iv = 0;
|
||||||
|
}
|
||||||
|
strcpy(options.binddn, "");
|
||||||
|
strcpy(options.password, "");
|
||||||
strcpy(options.searchbase, "");
|
strcpy(options.searchbase, "");
|
||||||
strcpy(options.hostname[0], "localhost");
|
strcpy(options.hostname[0], "localhost");
|
||||||
options.port[0] = LDAP_PORT;
|
options.port[0] = LDAP_PORT;
|
||||||
options.searchtimeout.tv_sec = DEF_SEARCHTIMEOUT;
|
options.searchtimeout.tv_sec = DEF_SEARCHTIMEOUT;
|
||||||
options.reclimit = DEF_RECLIMIT;
|
options.reclimit = DEF_RECLIMIT;
|
||||||
|
options.output = 0;
|
||||||
|
options.verbose = 0;
|
||||||
|
options.ldifname[0] = '\0';
|
||||||
|
strcpy(options.exec_command, "");
|
||||||
|
|
||||||
|
/* Attempt to parse the ldap.conf for system-wide valuse */
|
||||||
if (ldap_conf = fopen(LDAP_CONF, "r")) {
|
if (ldap_conf = fopen(LDAP_CONF, "r")) {
|
||||||
while(fgets(buf, 256, ldap_conf)!=0) {
|
while(fgets(buf, 256, ldap_conf)!=0) {
|
||||||
int i;
|
int i;
|
||||||
@@ -264,21 +283,51 @@ static int parse_options()
|
|||||||
}
|
}
|
||||||
fclose(ldap_conf);
|
fclose(ldap_conf);
|
||||||
}
|
}
|
||||||
strcpy(options.binddn, "");
|
|
||||||
strcpy(options.password, "");
|
/* Check the environment for process-local configuration overrides */
|
||||||
len = strlen(main_argv[0]);
|
if (getenv("LDAP2DNS_DAEMONIZE") != NULL) {
|
||||||
if (strcmp(main_argv[0]+len-9, "ldap2dnsd")==0) {
|
|
||||||
options.is_daemon = 1;
|
options.is_daemon = 1;
|
||||||
options.update_iv = UPDATE_INTERVAL;
|
ev = getenv("LDAP2DNS_UPDATE");
|
||||||
} else {
|
if (ev && sscanf(ev, "%d", &len)==1 && len>0) {
|
||||||
options.is_daemon = 0;
|
options.update_iv = len;
|
||||||
options.update_iv = 0;
|
} else {
|
||||||
|
/* We have not yet had a chance to override the default
|
||||||
|
* interval so use the default.
|
||||||
|
*/
|
||||||
|
options.update_iv = UPDATE_INTERVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ev = getenv("LDAP2DNS_UPDATE");
|
ev = getenv("LDAP2DNS_BINDDN");
|
||||||
if (ev && sscanf(ev, "%d", &len)==1 && len>0) {
|
if (ev) {
|
||||||
options.update_iv = len;
|
strncpy(options.binddn, ev, sizeof(options.binddn));
|
||||||
|
options.binddn[ sizeof(options.binddn) -1 ] = '\0';
|
||||||
|
ev = getenv("LDAP2DNS_PASSWORD");
|
||||||
|
if (ev){
|
||||||
|
strncpy(options.password, ev, sizeof(options.password));
|
||||||
|
options.password[ sizeof(options.password) -1 ] = '\0';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
options.output = 0;
|
ev = getenv("LDAP2DNS_BASEDN");
|
||||||
|
if (ev) {
|
||||||
|
strncpy(options.searchbase, ev, sizeof(options.searchbase));
|
||||||
|
options.searchbase[ sizeof(options.searchbase) -1 ] = '\0';
|
||||||
|
}
|
||||||
|
ev = getenv("LDAP2DNS_HOST");
|
||||||
|
if (ev) {
|
||||||
|
strncpy(options.hostname[options.usedhosts], ev, sizeof(options.hostname[options.usedhosts]));
|
||||||
|
options.hostname[options.usedhosts][ sizeof(options.hostname[options.usedhosts]) -1 ] = '\0';
|
||||||
|
options.usedhosts++;
|
||||||
|
ev = getenv("LDAP2DNS_PORT");
|
||||||
|
if (ev && sscanf(ev, "%hd", &tmp) != 1)
|
||||||
|
for (i = 0; i<MAXHOSTS; i++)
|
||||||
|
options.port[i] = tmp;
|
||||||
|
}
|
||||||
|
ev = getenv("LDAP2DNS_TIMEOUT");
|
||||||
|
if (ev && sscanf(ev, "%hd", &options.searchtimeout.tv_sec) != 1)
|
||||||
|
options.searchtimeout.tv_sec = DEF_SEARCHTIMEOUT;
|
||||||
|
ev = getenv("LDAP2DNS_RECLIMIT");
|
||||||
|
if (ev && sscanf(ev, "%d", &options.reclimit) != 1)
|
||||||
|
options.reclimit = DEF_RECLIMIT;
|
||||||
ev = getenv("LDAP2DNS_OUTPUT");
|
ev = getenv("LDAP2DNS_OUTPUT");
|
||||||
if (ev) {
|
if (ev) {
|
||||||
if (strcmp(ev, "data")==0)
|
if (strcmp(ev, "data")==0)
|
||||||
@@ -286,19 +335,16 @@ static int parse_options()
|
|||||||
else if (strcmp(ev, "db")==0)
|
else if (strcmp(ev, "db")==0)
|
||||||
options.output = OUTPUT_DB;
|
options.output = OUTPUT_DB;
|
||||||
}
|
}
|
||||||
ev = getenv("LDAP2DNS_BINDDN");
|
ev = getenv("LDAP2DNS_VERBOSE");
|
||||||
|
if (ev && sscanf(ev, "%hd", &options.verbose) != 1)
|
||||||
|
options.verbose = 0;
|
||||||
|
ev = getenv("LDAP2DNS_EXEC");
|
||||||
if (ev) {
|
if (ev) {
|
||||||
strncpy(options.binddn, ev, sizeof(options.binddn));
|
strncpy(options.exec_command, ev, sizeof(options.exec_command));
|
||||||
options.binddn[ sizeof(options.binddn)-1] = '\0';
|
options.exec_command[ sizeof( options.exec_command ) -1 ] = '\0';
|
||||||
ev = getenv("LDAP2DNS_PASSWORD");
|
|
||||||
if (ev){
|
|
||||||
strncpy(options.password, ev, sizeof(options.password));
|
|
||||||
options.password[ sizeof(options.password) -1 ] = '\0';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
options.verbose = 0;
|
|
||||||
options.ldifname[0] = '\0';
|
/* Finally, parse command-line options */
|
||||||
strcpy(options.exec_command, "");
|
|
||||||
while (1) {
|
while (1) {
|
||||||
int this_option_optind = optind ? optind : 1;
|
int this_option_optind = optind ? optind : 1;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
@@ -333,30 +379,30 @@ static int parse_options()
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
case 'b':
|
||||||
strncpy(options.searchbase, optarg, sizeof(options.searchbase));
|
strncpy(options.searchbase, optarg, sizeof(options.searchbase));
|
||||||
options.searchbase[ sizeof(options.searchbase) -1] = '\0';
|
options.searchbase[ sizeof(options.searchbase)-1 ] = '\0';
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
if (sscanf(optarg, "%d", &options.update_iv)!=1)
|
if (sscanf(optarg, "%d", &options.update_iv)!=1)
|
||||||
options.update_iv = UPDATE_INTERVAL;
|
options.update_iv = UPDATE_INTERVAL;
|
||||||
if (options.update_iv<=0) options.update_iv = 1;
|
if (options.update_iv<=0) options.update_iv = 1;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
strncpy(options.binddn, optarg, sizeof(options.binddn));
|
strncpy(options.binddn, optarg, sizeof(options.binddn));
|
||||||
options.binddn[ sizeof(options.binddn) -1 ] = '\0';
|
options.binddn[ sizeof(options.binddn) -1 ] = '\0';
|
||||||
break;
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
strncpy(options.hostname[0], optarg, sizeof(options.hostname[0]));
|
strncpy(options.hostname[options.usedhosts], optarg, sizeof(options.hostname[options.usedhosts]));
|
||||||
options.hostname[0][ sizeof(options.hostname[0]) -1 ] = '\0';
|
options.hostname[options.usedhosts][ sizeof(options.hostname[options.usedhosts]) -1 ] = '\0';
|
||||||
options.usedhosts = 1;
|
options.usedhosts++;
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
strncpy(options.urildap[0], optarg, sizeof(options.urildap[0]));
|
strncpy(options.urildap[0], optarg, sizeof(options.urildap[0]));
|
||||||
options.urildap[0][ sizeof( options.urildap[0] ) -1 ] = '\0';
|
options.urildap[0][ sizeof( options.urildap[0] ) -1 ] = '\0';
|
||||||
options.useduris = 1;
|
options.useduris = 1;
|
||||||
break;
|
break;
|
||||||
case 'L':
|
case 'L':
|
||||||
if (optarg==NULL)
|
if (optarg==NULL)
|
||||||
strcpy(options.ldifname, "-");
|
strcpy(options.ldifname, "-");
|
||||||
else{
|
else{
|
||||||
@@ -364,32 +410,32 @@ static int parse_options()
|
|||||||
options.ldifname[ sizeof( options.ldifname ) -1 ] = '\0';
|
options.ldifname[ sizeof( options.ldifname ) -1 ] = '\0';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
options.output = 0;
|
options.output = 0;
|
||||||
if (strcmp(optarg, "data")==0)
|
if (strcmp(optarg, "data")==0)
|
||||||
options.output = OUTPUT_DATA;
|
options.output = OUTPUT_DATA;
|
||||||
else if (strcmp(optarg, "db")==0)
|
else if (strcmp(optarg, "db")==0)
|
||||||
options.output = OUTPUT_DB;
|
options.output = OUTPUT_DB;
|
||||||
break;
|
break;
|
||||||
case 'p':
|
case 'p':
|
||||||
if (sscanf(optarg, "%hd", &options.port[0])!=1)
|
if (sscanf(optarg, "%hd", &options.port[0])!=1)
|
||||||
options.port[0] = LDAP_PORT;
|
options.port[0] = LDAP_PORT;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
if (optarg && optarg[0]=='v')
|
if (optarg)
|
||||||
options.verbose = 3;
|
options.verbose = strlen(optarg) + 1;
|
||||||
else
|
else
|
||||||
options.verbose = 1;
|
options.verbose = 1;
|
||||||
break;
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
print_version();
|
print_version();
|
||||||
exit(0);
|
exit(0);
|
||||||
case 'w':
|
case 'w':
|
||||||
strncpy(options.password, optarg, sizeof(options.password));
|
strncpy(options.password, optarg, sizeof(options.password));
|
||||||
options.password[ sizeof( options.password ) -1 ] = '\0';
|
options.password[ sizeof( options.password ) -1 ] = '\0';
|
||||||
memset(optarg, 'x', strlen(options.password));
|
memset(optarg, 'x', strlen(options.password));
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
strncpy(options.exec_command, optarg, sizeof(options.exec_command));
|
strncpy(options.exec_command, optarg, sizeof(options.exec_command));
|
||||||
options.exec_command[ sizeof( options.exec_command ) -1 ] = '\0';
|
options.exec_command[ sizeof( options.exec_command ) -1 ] = '\0';
|
||||||
break;
|
break;
|
||||||
@@ -398,7 +444,7 @@ static int parse_options()
|
|||||||
options.searchtimeout.tv_sec = DEF_SEARCHTIMEOUT;
|
options.searchtimeout.tv_sec = DEF_SEARCHTIMEOUT;
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
if (sscanf(optarg, "%hd", &options.reclimit)!=1)
|
if (sscanf(optarg, "%d", &options.reclimit)!=1)
|
||||||
options.reclimit = DEF_RECLIMIT;
|
options.reclimit = DEF_RECLIMIT;
|
||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
|
|||||||
Reference in New Issue
Block a user