#!/usr/bin/perl


use Term::ReadKey;
use Getopt::Long;
use Net::LDAP;



sub in_array {
	my ( $arr, $search ) = @_;
	return grep { $search eq $_ } @$arr;
}



sub help {
	print "\nUsage: bind2pdns-ldap --host=<host> --basedn=<dn> [--binddn=<dn>]\n";
	print "    --host      Host name or IP address of LDAP server (required)\n";
	print "    --basedn    Base DN of subtree which should be processed (required)\n";
	print "    --binddn    Bind DN for authentication\n";
	print "\n";
}



$host = "";
$binddn = "";
$basedn = "";

GetOptions(
	"host=s" => \$host,
	"binddn=s" => \$binddn,
	"basedn=s" => \$basedn,
);

if( $host eq "" || $basedn eq "" ) { help(); exit( 1 ); }



$ldap = Net::LDAP->new( $host ) or die "$@";

if( $binddn ne "" )
{
	print STDERR "Password: ";
	ReadMode('noecho');
	$pass = ReadLine(0);
	ReadMode('restore');
	print STDERR "\n";

	$mesg = $ldap->bind( $binddn, 'password' => $pass );
}
else
{
	$mesg = $ldap->bind();
}

if( $mesg->is_error ) { print 'Error in bind(): ' . $mesg->error(). "\n"; exit( 1 ); }

$mesg = $ldap->search(
	base => $basedn,
	filter => '(&(relativeDomainName=*)(zoneName=*))',
	attrs => [ 'objectClass', 'relativeDomainName', 'zoneName', 'dc', 'associatedDomain' ]
);
if( $mesg->is_error ) { print 'Error in search(): ' . $mesg->error(). "\n"; exit( 1 ); }

foreach $entry ( $mesg->entries )
{
	print "\n";

	print "dn: " . $entry->dn . "\n";
	print "changetype: modify\n";

	@classes = $entry->get_value( "objectClass" );

	if( @classes ) { print "replace: objectClass\n"; }
	else { print "add: objectClass\n"; }

	if( !in_array( \@classes, "dcObject" ) ) { push( @classes, "dcObject" ); }
	if( !in_array( \@classes, "dNSDomain2" ) ) { push( @classes, "dNSDomain2" ); }
	if( !in_array( \@classes, "domainRelatedObject" ) ) { push( @classes, "domainRelatedObject" ); }

	foreach my $entry ( @classes )
	{
		print "objectClass: " . $entry . "\n";
	}

	if( !$entry->get_value( "dc" ) )
	{
		print "-\n";
		print "add: dc\n";
		print "dc: " . $entry->get_value( "relativeDomainName" ) . "\n";
	}

	print "-\n";

	@domains = $entry->get_value( "associatedDomain" );

	if( @domains ) { print "replace: associatedDomain\n"; }
	else { print "add: associatedDomain\n"; }

	foreach my $zone ( $entry->get_value( "zoneName" ) )
	{
		foreach my $rdn ( $entry->get_value( "relativeDomainName" ) )
		{
			$domain = $rdn . "." . $zone;
			if( !in_array( \@domains, $domain ) ) { push( @domains, $domain ); }
		}
	}

	foreach my $entry ( @domains )
	{
		print "associatedDomain: " . $entry . "\n";
	}
}

$mesg = $ldap->unbind();
if( $mesg->is_error ) { print 'Error in unbind(): ' . $mesg->error(). "\n"; exit( 1 ); }

exit( 0 );
