Updated TODO

data2ldap.pl now works for all but unknown records and TXT records
Bumped Makefile version
Updated copyright information
Escaped TINYDNSDIR in ldap2tinydns-conf so it will always read the current value


git-svn-id: https://svn.alkaloid.net/gpl/ldap2dns/trunk@136 06cd67b6-e706-0410-b29e-9de616bca6e9
This commit is contained in:
Ben Klang
2005-12-08 17:27:56 +00:00
parent 6f091ec77f
commit 882629bf74
5 changed files with 296 additions and 38 deletions

View File

@@ -1,6 +1,6 @@
# $Id: Makefile,v 1.30 2003/01/20 14:33:25 jrief Exp $
VERSION=0.3.6
RELEASE=2
RELEASE=3
CC=gcc -O2
CCDEBUG=gcc -g
CFLAGS=$(INC) -DVERSION='"$(VERSION)"'

5
TODO
View File

@@ -1,2 +1,7 @@
* Add support for configuring basedn, binddn, bindpw, and execute command via
environment variables. (2005/12/07 bklang)
* Add support for reading more config params out of /etc/ldap.conf (at least
DNS search base DN, possibly more) (2005/12/07 bklang)
* Add possbility to search multiple LDAP hosts (2005/12/07 bklang)

View File

@@ -1,36 +1,41 @@
#!/usr/bin/perl
# To use this script, your tinydns data file must define dns zones
# before any records associated with that zone. For instance, to define the
# alkaloid.net zone the first record found by this script must either be a
# "Z" or "." record so that the tree is created in the proper order. Not
# following this rule will result in LDAP errors when importing the resulting
# dataset. To correct such an error just find all zone definitions and import
# those first, then add all records. This script may be extended to do that
# automatically for you at some point in the future but until that day follow
# this simple procedure and you shouldn't have any problems.
use strict;
use warnings;
my $file = $ARGV[0];
my $output = $ARGV[1];
my $rejout;
my $basedn = $ARGV[2];
my %domains; # Keep track of which domains for which we have
# already written an SOA
my $outfh;
my $rejfh;
if (!defined($file)) {
print STDERR "Must specify path to 'data' file to read\n";
exit 1;
}
if (!defined($output) || $file eq '-') {
if (!defined($output) || $output eq '-') {
$output = "/dev/stdout";
$rejout = "/dev/null";
} else {
$rejout = "$output.rej";
}
open($outfh, ">$output") or die ("Unable to open $output for writing!");
open($rejfh, ">$rejout") or die ("Unable to open $rejout for writing");
if (!defined($basedn)) {
print STDERR "Must specify a base DN as the third argument\n";
exit 1;
}
# We run in two iterations. The first attempts to enumerate all zones
# for which we have records and create SOAs in LDAP. The reason for this is
# zones are used as a container for all records so they must be in place before
# we start to add any zone data. While it takes longer, this mechanism ensures
# the proper sequence.
open(DATA, $file) or die ("Unable to open $file for reading\n");
LINE: while(<DATA>) {
chomp;
@@ -40,6 +45,13 @@ LINE: while(<DATA>) {
next LINE;
};
/^-/ && do {
# Found a disabled A record
print STDERR "Ignoring disabled record: $_\n";
print $rejfh "$_\n";
next LINE;
};
/^%/ && do {
# Location definition: %code:1.2.3.4
my ($loc, $ip) = split /:/;
@@ -49,7 +61,7 @@ LINE: while(<DATA>) {
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnsloccodes\n";
print $outfh "dnslocation: $loc\n";
if (defined($ip)) {
if (defined($ip) && $ip) {
print $outfh "dnsipaddr: $ip\n";
} else {
print $outfh "dnsipaddr: :\n";
@@ -68,17 +80,17 @@ LINE: while(<DATA>) {
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnszone\n";
print $outfh "cn: $domain\n";
print $outfh "dnszonename: v-office.biz\n";
if (defined($master)) { print $outfh "dnszonemaster: $master\n"; }
if (defined($admin)) { print $outfh "dnsadminmailbox: $admin\n"; }
if (defined($serial)) { print $outfh "dnsserial: $serial\n"; }
if (defined($refresh)) { print $outfh "dnsrefresh: $refresh\n"; }
if (defined($retry)) { print $outfh "dnsretry: $retry\n"; }
if (defined($expire)) { print $outfh "dnsexpire: $expire\n"; }
if (defined($minimum)) { print $outfh "dnsminimum: $minimum\n"; }
if (defined($ttl)) { print $outfh "dnsttl: $ttl\n"; }
if (defined($timestamp)) { print $outfh "dnstimestamp: $timestamp\n"; }
if (defined($loc)) { print $outfh "dnslocation: $loc\n"; }
print $outfh "dnszonename: $domain\n";
if ($master) { print $outfh "dnszonemaster: $master\n"; }
if ($admin) { print $outfh "dnsadminmailbox: $admin\n"; }
if ($serial) { print $outfh "dnsserial: $serial\n"; }
if ($refresh) { print $outfh "dnsrefresh: $refresh\n"; }
if ($retry) { print $outfh "dnsretry: $retry\n"; }
if ($expire) { print $outfh "dnsexpire: $expire\n"; }
if ($minimum) { print $outfh "dnsminimum: $minimum\n"; }
if ($ttl) { print $outfh "dnsttl: $ttl\n"; }
if ($timestamp) { print $outfh "dnstimestamp: $timestamp\n"; }
if ($loc) { print $outfh "dnslocation: $loc\n"; }
print $outfh "\n";
}; # End SOA record
@@ -87,16 +99,18 @@ LINE: while(<DATA>) {
my ($fqdn, $ip, $x, $ttl, $timestamp, $loc) = split /:/;
$fqdn =~ s/^\.//;
my $id = "$fqdn-$ip-$x-$ttl-$timestamp-$loc";
# To find the domain name, the fqdn must have two words of any
# characters with one period somehere in the middle and an optional
# trailing period (which is trimmed) just before the end of the line
$fqdn =~ /.\.*(.+\..+)\.*$/;
print STDERR "$1\n";
$fqdn =~ /^\.*([A-Za-z0-9-]+\.[A-Za-z0-9-]+)\.*$/;
if (!defined($1)) {
die ("Unable to find domain name for $fqdn!\n");
}
my $domain = $1;
my $domain = getdomain($fqdn);
if (defined($domains{$domain})) {
# We've already generated an SOA for this domain
next LINE;
}
print $outfh "dn: cn=$domain,$basedn\n";
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnszone\n";
@@ -105,7 +119,68 @@ print STDERR "$1\n";
if (defined($ttl)) { print $outfh "dnsttl: $ttl\n"; }
if (defined($timestamp)) { print $outfh "dnstimestamp: $timestamp\n"; }
if (defined($loc)) { print $outfh "dnslocation: $loc\n"; }
print $outfh "\n";
$domains{$domain} = 1;
next LINE;
};
} # End for($_) block
} # End LINE while(<DATA>)
# Done with zone SOAs, being with resource records
seek(DATA, 0, 0) or die ("Unable to seek $file for reading\n");
LINE: while(<DATA>) {
chomp;
for ($_) {
/^\s*#/ && do {
# Found a comment
next LINE;
};
/^-/ && do {
# Found a disabled. User was warned above
next LINE;
};
/^\./ && do {
# Found NS + A + SOA (SOA handled above)
my ($fqdn, $ip, $x, $ttl, $timestamp, $loc) = split /:/;
$fqdn =~ s/^\.//;
if (!defined($ip)) { $ip = ""; }
if (!defined($x)) { $x = ""; }
if (!defined($ttl)) { $ttl = ""; }
if (!defined($timestamp)) { $timestamp = ""; }
if (!defined($loc)) { $loc = ""; }
my $id = "NSA-$fqdn-$ip-$x-$ttl-$timestamp-$loc";
my $domain = getdomain($fqdn);
print $outfh "dn: cn=$id,cn=$domain,$basedn\n";
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnszone\n";
print $outfh "objectClass: dnsrrset\n";
print $outfh "cn: $id\n";
print $outfh "dnstype: a\n";
print $outfh "dnsdomainname: $fqdn.\n";
if ($x) { print $outfh "dnscname: $x\n"; }
if ($ip) { print $outfh "dnsipaddr: $ip\n"; }
if ($ttl) { print $outfh "dnsttl: $ttl\n"; }
if ($timestamp) { print $outfh "dnstimestamp: $timestamp\n"; }
if ($loc) { print $outfh "dnsloc: $loc\n"; }
print $outfh "\n";
next LINE;
};
/^&/ && do {
# Found NS
my ($fqdn, $ip, $x, $ttl, $timestamp, $loc) = split /:/;
$fqdn =~ s/^&//;
if (!defined($ip)) { $ip = ""; }
if (!defined($x)) { $x = ""; }
if (!defined($ttl)) { $ttl = ""; }
if (!defined($timestamp)) { $timestamp = ""; }
if (!defined($loc)) { $loc = ""; }
my $id = "NS-$fqdn-$ip-$x-$ttl-$timestamp-$loc";
my $domain = getdomain($fqdn);
print $outfh "dn: cn=$id,cn=$domain,$basedn\n";
print $outfh "objectClass: top\n";
@@ -113,14 +188,190 @@ print STDERR "$1\n";
print $outfh "objectClass: dnsrrset\n";
print $outfh "cn: $id\n";
print $outfh "dnstype: ns\n";
if (index($x, /\./) > -1) {
print $outfh "dnsdomainname: $x.\n";
} else {
print $outfh "dnsdomainname: $x.ns.$fqdn.\n";
}
if (defined($ip)) { print $outfh "dnscipaddr: $ip\n"; }
print $outfh "dnsdomainname: $fqdn.\n";
if ($ip) { print $outfh "dnsipaddr: $ip\n"; }
if ($x) { print $outfh "dnscname: $x\n"; }
if ($ttl) { print $outfh "dnsttl: $ttl\n"; }
if ($timestamp) { print $outfh "dnstimestamp: $timestamp\n"; }
if ($loc) { print $outfh "dnsloc: $loc\n"; }
print $outfh "\n";
next LINE;
};
/^=/ && do {
# Found an A + PTR
my ($fqdn, $ip, $ttl, $timestamp, $loc) = split /:/;
$fqdn =~ s/^=//;
if (!defined($ip)) { $ip = ""; }
if (!defined($ttl)) { $ttl = ""; }
if (!defined($timestamp)) { $timestamp = ""; }
if (!defined($loc)) { $loc = ""; }
my $id = "APTR-$fqdn-$ip-$ttl-$timestamp-$loc";
my $domain = getdomain($fqdn);
print $outfh "dn: cn=$id,cn=$domain,$basedn\n";
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnszone\n";
print $outfh "objectClass: dnsrrset\n";
print $outfh "cn: $id\n";
print $outfh "dnstype: a\n";
print $outfh "dnsdomainname: $fqdn.\n";
if ($ip) { print $outfh "dnscipaddr: $ip\n"; }
if ($ttl) { print $outfh "dnsttl: $ttl\n"; }
if ($timestamp) { print $outfh "dnstimestamp: $timestamp\n"; }
if ($loc) { print $outfh "dnsloc: $loc\n"; }
print $outfh "\n";
next LINE;
};
/^\+/ && do {
# Found an A
my ($fqdn, $ip, $ttl, $timestamp, $loc) = split /:/;
$fqdn =~ s/^\+//;
if (!defined($ip)) { $ip = ""; }
if (!defined($ttl)) { $ttl = ""; }
if (!defined($timestamp)) { $timestamp = ""; }
if (!defined($loc)) { $loc = ""; }
my $id = "A-$fqdn-$ip-$ttl-$timestamp-$loc";
my $domain = getdomain($fqdn);
print $outfh "dn: cn=$id,cn=$domain,$basedn\n";
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnszone\n";
print $outfh "objectClass: dnsrrset\n";
print $outfh "cn: $id\n";
print $outfh "dnstype: a\n";
print $outfh "dnsdomainname: $fqdn.\n";
if ($ip) { print $outfh "dnsipaddr: $ip\n"; }
if ($ttl) { print $outfh "dnsttl: $ttl\n"; }
if ($timestamp) { print $outfh "dnstimestamp: $timestamp\n"; }
if ($loc) { print $outfh "dnsloc: $loc\n"; }
print $outfh "\n";
next LINE;
};
/^@/ && do {
# Found an MX
my ($fqdn, $ip, $x, $dist, $ttl, $timestamp, $loc) = split /:/;
$fqdn =~ s/^@//;
if (!defined($ip)) { $ip = ""; }
if (!defined($x)) { $x = ""; }
if (!defined($dist)) { $dist = ""; }
if (!defined($ttl)) { $ttl = ""; }
if (!defined($timestamp)) { $timestamp = ""; }
if (!defined($loc)) { $loc = ""; }
my $id = "MX-$fqdn-$ip-$x-$dist-$ttl-$timestamp-$loc";
my $domain = getdomain($fqdn);
print $outfh "dn: cn=$id,cn=$domain,$basedn\n";
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnszone\n";
print $outfh "objectClass: dnsrrset\n";
print $outfh "cn: $id\n";
print $outfh "dnstype: mx\n";
print $outfh "dnsdomainname: $fqdn.\n";
if ($ip) { print $outfh "dnsipaddr: $ip\n" };
if ($x) { print $outfh "dnscname: $x\n"; }
if ($dist) { print $outfh "dnspreference: $dist\n"; }
if ($ttl) { print $outfh "dnsttl: $ttl\n"; }
if ($timestamp) { print $outfh "dnstimestamp: $timestamp\n"; }
if ($loc) { print $outfh "dnsloc: $loc\n"; }
print $outfh "\n";
next LINE;
};
/^'/ && do {
# Currently unsupported
print STDERR "Ignoring unsupported TXT record: $_\n";
print $rejfh "$_\n";
next LINE;
# Found an MX
my ($fqdn, $s, $ttl, $timestamp, $loc) = split /:/;
$fqdn =~ s/^'//;
if (!defined($ttl)) { $ttl = ""; }
if (!defined($timestamp)) { $timestamp = ""; }
if (!defined($loc)) { $loc = ""; }
my $id = "TXT-$fqdn-$ttl-$timestamp-$loc";
my $domain = getdomain($fqdn);
print $outfh "dn: cn=$id,cn=$domain,$basedn\n";
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnszone\n";
print $outfh "objectClass: dnsrrset\n";
print $outfh "cn: $id\n";
print $outfh "dnstype: txt\n";
print $outfh "dnsdomainname: $fqdn.\n";
# FIXME Add TXT support to ldap2dns
# print $outfh "dnstxt: $s\n";
if ($ttl) { print $outfh "dnsttl: $ttl\n"; }
if ($timestamp) { print $outfh "dnstimestamp: $timestamp\n"; }
if ($loc) { print $outfh "dnsloc: $loc\n"; }
print $outfh "\n";
next LINE;
};
/^\^/ && do {
# Found an PTR
my ($fqdn, $ptr, $ttl, $timestamp, $loc) = split /:/;
$fqdn =~ s/^\^//;
if (!defined($ttl)) { $ttl = ""; }
if (!defined($timestamp)) { $timestamp = ""; }
if (!defined($loc)) { $loc = ""; }
my $id = "$fqdn-$ptr-$ttl-$timestamp-$loc";
my $domain = getdomain($fqdn);
print $outfh "dn: cn=$id,cn=$domain,$basedn\n";
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnszone\n";
print $outfh "objectClass: dnsrrset\n";
print $outfh "cn: $id\n";
print $outfh "dnstype: ptr\n";
print $outfh "dnscname: $fqdn.\n";
print $outfh "dnsipaddr: $ptr\n";
if ($ttl) { print $outfh "dnsttl: $ttl\n"; }
if ($timestamp) { print $outfh "dnstimestamp: $timestamp\n"; }
if ($loc) { print $outfh "dnsloc: $loc\n"; }
print $outfh "\n";
next LINE;
};
/^C/ && do {
# Found a CNAME
my ($fqdn, $p, $ttl, $timestamp, $loc) = split /:/;
$fqdn =~ s/^C//;
if (!defined($ttl)) { $ttl = ""; }
if (!defined($timestamp)) { $timestamp = ""; }
if (!defined($loc)) { $loc = ""; }
my $id = "CNAME-$fqdn-$p-$ttl-$timestamp-$loc";
my $domain = getdomain($fqdn);
print $outfh "dn: cn=$id,cn=$domain,$basedn\n";
print $outfh "objectClass: top\n";
print $outfh "objectClass: dnszone\n";
print $outfh "objectClass: dnsrrset\n";
print $outfh "cn: $id\n";
print $outfh "dnstype: cname\n";
print $outfh "dnsdomainname: $fqdn.\n";
print $outfh "dnscname: $p.\n";
if ($ttl) { print $outfh "dnsttl: $ttl\n"; }
if ($timestamp) { print $outfh "dnstimestamp: $timestamp\n"; }
if ($loc) { print $outfh "dnsloc: $loc\n"; }
print $outfh "\n";
next LINE;
};
/^:/ && do {
# Found unsupported "unknown record"
print STDERR "Ignoring \"unknown record\": $_\n";
print $rejfh "$_\n";
next LINE;
}
} # End for($_) block
} # End LINE while(<DATA>)
sub getdomain
{
my $fqdn = shift(@_);
$fqdn =~ /\.*([A-Za-z0-9\-]+\.[A-Za-z0-9\-]+)\.*$/;
return $1;
}

View File

@@ -1,8 +1,9 @@
/*
* Create data from an LDAP directory service to be used for tinydns
* $Id: ldap2dns.c,v 1.33 2003/01/20 14:33:25 jrief Exp $
* Copyright 2000 by Jacob Rief <jacob.rief@tiscover.com>
* License: GPL version 2 or later. See http://www.fsf.org for details
* $Id: ldap2dns.c,v 1.36 2005/12/07 19:03:11 bklang Exp $
* Copyright 2000-2005 by Jacob Rief <jacob.rief@tiscover.com>
* Copyright 2005 by Ben Klang <ben@alkaloid.net>
* License: GPL version 2. See http://www.fsf.org for details
*/
#include <lber.h>
@@ -34,7 +35,8 @@ static int main_argc;
static void print_version(void)
{
printf("ldap2dns, version %s\n", VERSION);
printf(" Copyright 2000 by Jacob Rief <jacob.rief@tiscover.com>\n\n");
printf(" Copyright 2000-2005 by Jacob Rief <jacob.rief@tiscover.com>\n\n");
printf(" Copyright 2000 by Ben Klang <ben@alkaloid.net>\n");
}

View File

@@ -21,7 +21,7 @@ touch $LDAP2DNSDIR/log/status
cat << EOF_run > $LDAP2DNSDIR/run
#!/bin/sh
exec 2>&1
exec setuidgid $LDAP2DNSUSER envdir ./env softlimit -d250000 /usr/bin/ldap2dns -e "cd $TINYDNSDIR && tinydns-data"
exec setuidgid $LDAP2DNSUSER envdir ./env softlimit -d250000 /usr/bin/ldap2dns -e "cd \$TINYDNSDIR && tinydns-data"
EOF_run
chmod +t $LDAP2DNSDIR