mirror of
				https://github.com/bklang/ldap2dns.git
				synced 2025-11-04 08:53:12 -05:00 
			
		
		
		
	Created scripts directory moved data2ldap.pl and axfr2ldap.pl into scripts Updated TODO git-svn-id: https://svn.alkaloid.net/gpl/ldap2dns/trunk@139 06cd67b6-e706-0410-b29e-9de616bca6e9
		
			
				
	
	
		
			191 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			191 lines
		
	
	
		
			5.9 KiB
		
	
	
	
		
			Perl
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/perl
 | 
						|
# Script to import data from DNS into LDAP
 | 
						|
# Copyright 2000, Jacob Rief
 | 
						|
# $Id: export-ldap2dns.pl,v 1.1 2002/09/03 10:43:40 jrief Exp $
 | 
						|
 | 
						|
###### configure this ######
 | 
						|
# remember to allow zone transfers from Your nameserver
 | 
						|
my $LDAPHOST = "localhost";
 | 
						|
my $LDAPBINDDN = "uid=root,o=tiscover";
 | 
						|
my $LDAPPASSWD = "XXXXXXX";
 | 
						|
my $BASEDN = "ou=dns,o=tiscover";
 | 
						|
 | 
						|
###### don't edit below this line ######
 | 
						|
use strict;
 | 
						|
use Net::LDAP qw(LDAP_NO_SUCH_OBJECT LDAP_ALREADY_EXISTS);
 | 
						|
 | 
						|
my $ldap;
 | 
						|
initialize();
 | 
						|
migrate_zones();
 | 
						|
 | 
						|
sub initialize
 | 
						|
{
 | 
						|
	$ldap = Net::LDAP->new($LDAPHOST) or die "Can't connect to LDAP server";
 | 
						|
	my $mesg = $ldap->bind( dn => $LDAPBINDDN, password => $LDAPPASSWD );
 | 
						|
	die "Unable to bind to LDAP ", $mesg->error if ($mesg->code);
 | 
						|
}
 | 
						|
 | 
						|
sub migrate_zones
 | 
						|
{
 | 
						|
	my $mesg = $ldap->search(base=>$BASEDN, scope=>'sub', filter=>"(objectclass=dnszone)");
 | 
						|
	my @oldzones = $mesg->entries();
 | 
						|
	foreach my $oldzone (@oldzones) {
 | 
						|
		my @zonename = $oldzone->get_value('dnszonename');
 | 
						|
		my $masterdn = dn_domain($zonename[0]) if ($#zonename>=0);
 | 
						|
		foreach my $zn (@zonename) {
 | 
						|
			my $newdn = dn_domain($zn);
 | 
						|
			next unless ($newdn =~ /^dc=\s*([^,]+).*/);
 | 
						|
			my $dc = $1;
 | 
						|
			my $soarecord = $oldzone->get_value('dnsserial')." "
 | 
						|
			    .$oldzone->get_value('dnsrefresh')." "
 | 
						|
			    .$oldzone->get_value('dnsretry')." "
 | 
						|
			    .$oldzone->get_value('dnsexpire')." "
 | 
						|
			    .$oldzone->get_value('dnsminimum');
 | 
						|
			my %attrs = ( 'objectclass' => [ qw(dNSDomain dcObject) ], 'dc' => $dc, 'sOARecord' => [ $soarecord ] );
 | 
						|
			$mesg = $ldap->modify($newdn, 'replace' => \%attrs);
 | 
						|
			while ($mesg->code()==LDAP_NO_SUCH_OBJECT) {
 | 
						|
			    repeat:
 | 
						|
				$mesg = $ldap->add($newdn, 'attrs' => list_attrs(\%attrs));
 | 
						|
				last unless ($mesg->code()==LDAP_NO_SUCH_OBJECT);
 | 
						|
				my $filldn = $newdn;
 | 
						|
				do {
 | 
						|
					die("Invalid dn: $filldn") unless ($filldn =~ /[^,]+,((dc=[^,]+),.+)/);
 | 
						|
					$filldn = $1;
 | 
						|
					$mesg = $ldap->add($filldn, 'attrs' => [ 'objectclass'=>'dcObject', 'dc'=>$2) ]);
 | 
						|
				} until ($mesg->code()==0 || $mesg->code()==LDAP_ALREADY_EXISTS);
 | 
						|
				goto repeat;
 | 
						|
			}
 | 
						|
			die("Error from LDAP: \"".$mesg->error()."\" on $newdn (".$mesg->code().")") if ($mesg->code());
 | 
						|
			if ($masterdn ne $newdn) {
 | 
						|
				$mesg = $ldap->modify($masterdn, 'replace' => [ 'objectclass' => 'alias' ]);
 | 
						|
				$mesg = $ldap->modify($masterdn, 'add' => [ 'alias' => $newdn ]);
 | 
						|
				$mesg = $ldap->modify($newdn, 'replace' => [ 'objectclass' => 'alias', 'alias' => $masterdn ]);
 | 
						|
			}
 | 
						|
			migrate_rrrecords($zn, $newdn, $oldzone->dn());
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
sub migrate_rrrecords
 | 
						|
{
 | 
						|
	my ($zonename, $newzonedn, $oldzonedn) = (@_);
 | 
						|
	my @objectclass = qw(dNSDomain dcObject);
 | 
						|
	my $mesg = $ldap->search(base=>$oldzonedn, scope=>'sub', filter=>"(objectclass=dnsrrset)");
 | 
						|
	my @rrsets = $mesg->entries();
 | 
						|
	foreach my $rr (@rrsets) {
 | 
						|
		my $domainname = $rr->get_value('dnsdomainname');
 | 
						|
		my $dn = dn_domain(length($domainname)>0 ? "$domainname.$zonename" : "$zonename");
 | 
						|
		my $type = $rr->get_value('dnstype');
 | 
						|
		print "dn: $dn (type: $type)\n";
 | 
						|
		next unless ($dn =~ /^dc=\s*([^,]+).*/);
 | 
						|
		my %attrs = read_ldapobject($dn);
 | 
						|
		$attrs{'objectclass'} = \@objectclass;
 | 
						|
		$attrs{'dc'} = $1;
 | 
						|
		my @cname = $rr->get_value('dnscname');
 | 
						|
		my @ipaddr = $rr->get_value('dnsipaddr');
 | 
						|
		my $cipaddr = $rr->get_value('dnscipaddr');
 | 
						|
		if ($type eq "A") {
 | 
						|
			push(@ipaddr, $cipaddr) if (length($cipaddr)>5);
 | 
						|
			my $ta = $attrs{'aRecord'};
 | 
						|
			push(@$ta, @ipaddr) if ($#ipaddr>=0);
 | 
						|
		} elsif ($type eq "NS") {
 | 
						|
			my $ta = $attrs{'NSRecord'};
 | 
						|
			foreach my $cn (@cname) {
 | 
						|
				if ($cn =~ /\.$/) {
 | 
						|
					push(@$ta, $cn);
 | 
						|
				} else {
 | 
						|
					push(@$ta, "$cn.$zonename");
 | 
						|
				}
 | 
						|
			}
 | 
						|
		} elsif ($type eq "MX") {
 | 
						|
			my $ta = $attrs{'MXRecord'};
 | 
						|
			my $pref = $rr->get_value('dnspreference');
 | 
						|
			foreach my $cn (@cname) {
 | 
						|
				if ($cn =~ /\.$/) {
 | 
						|
					push(@$ta, "$pref $cn");
 | 
						|
				} else {
 | 
						|
					push(@$ta, "$pref $cn.$zonename");
 | 
						|
				}
 | 
						|
			}
 | 
						|
		} elsif ($type eq "CNAME") {
 | 
						|
			my $ta = $attrs{'cNAMERecord'};
 | 
						|
			die("no CNAME") unless($#cname>=0);
 | 
						|
			foreach my $cn (@cname) {
 | 
						|
				if ($cn =~ /\.$/) {
 | 
						|
					push(@$ta, $cn);
 | 
						|
				} else {
 | 
						|
					push(@$ta, "$cn.$zonename");
 | 
						|
				}
 | 
						|
			}
 | 
						|
		}
 | 
						|
		remove_unused(\%attrs);
 | 
						|
		$mesg = $ldap->modify($dn, 'replace' => \%attrs);
 | 
						|
		while ($mesg->code()==LDAP_NO_SUCH_OBJECT) {
 | 
						|
		    repeat:
 | 
						|
			$mesg = $ldap->add($dn, 'attrs' => list_attrs(\%attrs));
 | 
						|
			last unless ($mesg->code()==LDAP_NO_SUCH_OBJECT);
 | 
						|
			my $filldn = $dn;
 | 
						|
			do {
 | 
						|
				die("Invalid dn: $filldn") unless ($filldn =~ /[^,]+,((dc=[^,]+),.+)/);
 | 
						|
				$filldn = $1;
 | 
						|
				$mesg = $ldap->add($filldn, 'attrs' => [ qw(objectclass dcObject dc $2) ]);
 | 
						|
			} until ($mesg->code()==0 || $mesg->code()==LDAP_ALREADY_EXISTS);
 | 
						|
			goto repeat;
 | 
						|
		}
 | 
						|
		die("Error from LDAP: \"".$mesg->error()."\" on $dn") if ($mesg->code());
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
sub dn_domain
 | 
						|
{
 | 
						|
	my ($domain)=(@_);
 | 
						|
	my @p = split /\./, lc($domain);
 | 
						|
	my $dc = 'dc='.join(',dc=', @p);
 | 
						|
	$dc .= ','.$BASEDN;
 | 
						|
	return $dc;
 | 
						|
}
 | 
						|
 | 
						|
sub list_attrs
 | 
						|
{
 | 
						|
        my $attr = shift;
 | 
						|
        my (@list, $key, $value);
 | 
						|
        while (($key, $value) = each %$attr) {
 | 
						|
                push(@list, $key => $value);
 | 
						|
        }
 | 
						|
        return \@list;
 | 
						|
}
 | 
						|
 | 
						|
sub read_ldapobject
 | 
						|
{
 | 
						|
	my $dn = shift;
 | 
						|
	my %attrs = ();
 | 
						|
	$attrs{'aRecord'} = [];
 | 
						|
	$attrs{'cNAMERecord'} = [];
 | 
						|
	$attrs{'MXRecord'} = [];
 | 
						|
	$attrs{'NSRecord'} = [];
 | 
						|
	my $mesg = $ldap->search(base => $dn, scope => 'base', filter => "(objectclass=dcObject)");
 | 
						|
	return %attrs if ($mesg->code()==LDAP_NO_SUCH_OBJECT);
 | 
						|
	return %attrs if ($mesg->count()==0);
 | 
						|
	my $obj = $mesg->entry(0);
 | 
						|
	my @tempa = $obj->get_value('aRecord');
 | 
						|
	$attrs{'aRecord'} = \@tempa if ($#tempa>=0);
 | 
						|
	my @tempcname = $obj->get_value('cNAMERecord');
 | 
						|
	$attrs{'cNAMERecord'} = \@tempcname if ($#tempcname>=0);
 | 
						|
	my @tempmx = $obj->get_value('MXRecord');
 | 
						|
	$attrs{'MXRecord'} = \@tempmx if ($#tempmx>=0);
 | 
						|
	my @tempns = $obj->get_value('NSRecord');
 | 
						|
	$attrs{'NSRecord'} = \@tempns if ($#tempns>=0);
 | 
						|
	return %attrs;
 | 
						|
}
 | 
						|
 | 
						|
sub remove_unused
 | 
						|
{
 | 
						|
	my $hash = shift;
 | 
						|
	foreach my $key (keys %$hash) {
 | 
						|
		my $ta = $$hash{$key};
 | 
						|
		next if ($key eq "dc");
 | 
						|
		delete $$hash{$key} if ($#$ta<0);
 | 
						|
	}
 | 
						|
}
 | 
						|
 |