#!/usr/bin/perl  -w
##
## Convert an LDIF file containing qmailUser and radiusUser entries
## to the use the inetOrgperson objectclass and correct schema problems
##
## Buchan Milne <bgmilne@obsidian.co.za>
##
##
## Based on convertSambaAccount, distributed with the samba source,
## Copyright Gerald (Jerry) Carter	2003
##
## Usage: convertSambaAccount \
##       --input=<input ldif> --output=<output ldif> \
##       --changetype=[modify|add]
##


use strict;
use Net::LDAP::LDIF;
use Getopt::Long;


##############################################################################
## local variables

my ( $domain, $domsid, $changetype );
my ( $ldif, $ldif2 );
my ( $entry, @objclasses, $obj );
my ( $is_qmail_account, $is_radius_account );
my ( %attr_map, %group_attr_map, $key );
my ( @dels, $deletion, @adds, $addition );
my ( $result, %options );


##############################################################################
## Print the option usage

sub usage {

	print "$0 <options>\n";
	print "Options:\n";
	print "  --help         print this help message\n";
	print "  --input        input LDIF filename\n";
	print "  --output       output LDIF filename\n";
	print "  --changetype   [modify|add] (default is 'add')\n";
}


##############################################################################
##                               MAIN DRIVER                                ##
##############################################################################

##
## hashes to map old attribute names to new ones 
##

%attr_map = ( 
);

%group_attr_map = (
);

##
## process command line args
##

$result = GetOptions(\%options,
			"help", 
			"input=s", 
			"output=s", 
			"changetype=s");

if (!$result && ($#ARGV != -1)) {
	usage();
	exit 1;
}

if ( defined($options{'help'}) ) {
	usage();
	exit 0;
}


$changetype = 'add';
if ( defined( $options{'changetype'} ) ) {
	$changetype = $options{'changetype'};
}

##
## open files
##

$ldif = Net::LDAP::LDIF->new ($options{'input'}, "r") or die $!;

if ( "$changetype" eq "add" ) {
	$ldif2 = Net::LDAP::LDIF->new ($options{'output'}, "w") or die $!;
}
elsif ( "$changetype" eq "modify" ) {
	open( OUTPUT, ">$options{'output'}" ) or die $!;
}
else {
	print "Bad changetype!\n";
	exit 1;
}

##
## process LDIF 
##

while ( !$ldif->eof ) {
	undef ( $entry );
	$entry = $ldif->read_entry();

	## skip entry if we find an error
	if ( $ldif->error() ) {
		print "Error msg: ",$ldif->error(),"\n";
		print "Error lines:\n",$ldif->error_lines(),"\n";
		next;
	}

	##
	## check to see if we have anything to do on this
	## entry.  If not just write it out
	##
	@objclasses = $entry->get_value( "objectClass" );
	undef ( $is_qmail_account );
	@adds = ();
	@dels = ();
	foreach $obj ( @objclasses ) {
		if ( "$obj" eq "qmailUser" ) {
			$is_qmail_account = 1;
		}
	}

	if ( defined ( $is_qmail_account ) ) {
		##
		## start editing the qmailUser
		##

		@dels = ( );
		#@adds = ('objectclass: inetOrgPerson','objectclass: infranetUser');
		@adds = ( );
		$entry->add( 'objectClass' => 'inetOrgPerson' );
		$entry->add( 'sn' => $entry->get_value( "uid"));

		if (defined($entry->get_value( "cn" ))) {
			$entry->add( 'cn' => $entry->get_value( "uid"));
		}
	

		foreach $key ( keys %attr_map ) {
			if ( defined($entry->get_value($key)) ) {
				push @adds, "$attr_map{$key}: " . $entry->get_value($key);
				push @dels, "$key";
				$entry->add( $attr_map{$key} => $entry->get_value($key) );
				$entry->delete( $key );
			}
		}
	}
	
	## see if we should write full entries or only the changes
	
	if ( "$changetype" eq "add" ) {
		$ldif2->write_entry( $entry );
	}
	else {
		if ( defined ( $is_qmail_account ) ){
			if ( @adds + @dels > 0 ) {
				print OUTPUT "dn: " . $entry->dn . "\n";
				foreach $addition (@adds) {
					$addition =~ /(^\w+):/;
					print OUTPUT "add: " . $1  . "\n";
					print OUTPUT "$addition\n-\n";
				}
				foreach $deletion (@dels) {
					if ( $deletion =~ /^(\w+):\s(.*)/ ) {
						print OUTPUT "delete: $1\n$1: $2\n-\n";
					} else {
						print OUTPUT "delete: $deletion\n-\n"
					}
				}
				print OUTPUT "\n"
			}
		}
	}
}


