ispman/scripts ldifupdate,1.2,1.2.2.1

[email protected]
Newsgroups gmane.comp.isp.ispman.cvs
Message-ID <[email protected]>
Update of /cvsroot/ispman/ispman/scripts
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv21791

Modified Files:
      Tag: rel_1_1-bugfixes
	ldifupdate 
Log Message:
merge from HEAD


Index: ldifupdate
===================================================================
RCS file: /cvsroot/ispman/ispman/scripts/ldifupdate,v
retrieving revision 1.2
retrieving revision 1.2.2.1
diff -u -d -r1.2 -r1.2.2.1
--- ldifupdate	18 Jan 2004 20:03:19 -0000	1.2
+++ ldifupdate	1 Feb 2004 14:24:46 -0000	1.2.2.1
@@ -10,19 +10,6 @@
 # according to current schema
 # For details see comments below
 
-
-sub usage {
-    print "ISPMan ldifupdate\n";
-    print "A utility to update your ispman LDAP data according to current ISPMan schema.\n";
-    print "It will convert the given input LDIF and output it to an output LDIF\n";
-    print "either in add or modify format.\n\n";
-    print "Syntax: ldifupdate <options>\n";
-    print "Options:\n";
-    print "  -i        input LDIF filename\n"; 
-    print "  -o        output LDIF filename\n"; 
-    print "  -b        base DN (optional), which limits changes to this subtree\n"; 
-}
-
 use strict;
 use Getopt::Std;
 use Net::LDAP::LDIF;
@@ -38,32 +25,120 @@
 my $dummyUid = "999999";
 my $dummyGid = "999999";
 my $dummyPassword = "123456";
+my $mode;
+
+# private variables
+my ($ldif_in, $ldif_out, $entry, $basedn);
+my (%opts, $dn, $msg, $chng);
+
+
+
+sub usage {
+    print "ISPMan ldifupdate\n";
+    print "A utility to update your ispman LDAP data according to current ISPMan schema.\n";
+    print "It will convert the given input LDIF and output it to an output LDIF\n";
+    print "either in add or modify format.\n\n";
+    print "Syntax: ldifupdate <options>\n";
+    print "Options:\n";
+    print "  -i <file>        input LDIF filename\n"; 
+    print "  -o <file>        output LDIF filename\n"; 
+    print "  -b <basedn>      base DN (optional), which limits changes to this subtree\n"; 
+    print "  -m <add/modify>  type of LDIF to create (default=add)\n";
+}
+
+sub ldif_action {
+    my ($cmd,$attr,$attrval)=@_;
+    my $ldif;
+
+    # modify entry
+    if ($cmd eq "delete"){
+	$entry->delete($attr => [$attrval]);
+    } else {
+	$entry->$cmd($attr,$attrval);
+    }
+
+    # generate ldif change
+    $ldif="$cmd: $attr\n";
+    if (ref $attrval eq "ARRAY"){
+	for (@$attrval){ $ldif.="$attr: $_\n"; }
+    } else {
+	$ldif.="$attr: $attrval\n";
+    }
+
+    $ldif.="-\n";
+
+    # write ldif change to global var
+    $chng.=$ldif;
+}
+
+    
+sub update_oc {
+    my ($entry,$src, $dst)=@_;
+    my $msg="";
+    my %in_src;
+    my %in_dst;
+    
+    for (@$src) { $in_src{$_}=1; }
+    for (@$dst) {
+	if (! $in_src{$_}) {
+	    $msg.="adding objectclass: \"$_\"\n";
+	    ldif_action("add","objectclass",$_);
+	}
+	$in_dst{$_}=1;
+    }
+    for (@$src) {
+	if (! $in_dst{$_}) {
+	    $msg.="deleting objectclass: \"$_\"\n";
+	    ldif_action("delete","objectclass",$_);
+	}
+    }
+    
+    return $msg;
+}
+
+
+## main
 
-# local variables
-my ($ldif, $ldif2, $entry, $basedn);
-my (%opts, $dn, $msg);
 
 # get parameters
-getopt('iob',  \%opts);
+getopt('iobm',  \%opts);
 unless ($opts{'i'} or $opts{'o'}){
     usage();
     exit 1;
 }
 
-$ldif = Net::LDAP::LDIF->new( $opts{'i'});
-$ldif2 = Net::LDAP::LDIF->new( $opts{'o'}, "w");
+# set mode
+$mode=$opts{'m'} || "add";
+
+if ($mode ne "add" and $mode ne "modify"){
+    print STDERR "unknown mode: $mode\n";
+    usage();
+    exit 1;
+}
+
+
+# input file
+$ldif_in= Net::LDAP::LDIF->new( $opts{'i'});
+
+# output file
+if ($mode eq "add"){
+    $ldif_out = Net::LDAP::LDIF->new( $opts{'o'}, "w");
+} else {
+    open(OUTLDIF,">$opts{'o'}") || die "unable to create $opts{'o'}\n";
+}
 
+# only work on entries of this basedn
 $basedn = $opts{'b'};
 
 # read and parse ldap data
-while( not $ldif->eof() ) {
+while( not $ldif_in->eof() ) {
     undef ($entry);
-    $entry = $ldif->read_entry();
+    $entry = $ldif_in->read_entry();
     
     # skip entry if we find an error
-    if ( $ldif->error() ) {
-        print STDERR "Error msg: ",$ldif->error(),"\n";
-        print STDERR "Error lines:\n",$ldif->error_lines(),"\n";
+    if ( $ldif_in->error() ) {
+        print STDERR "Error msg: ",$ldif_in->error(),"\n";
+        print STDERR "Error lines:\n",$ldif_in->error_lines(),"\n";
     }
 
     $entry->changetype("add");
@@ -72,42 +147,43 @@
     next unless ! defined($basedn) or $dn =~ m/$basedn$/;
 
     $msg="";
+    $chng="";
 
-    ## update entry
     my @oc=$entry->get_value("objectclass");
+    my %oc;
+    for (@oc) { $oc{$_}=1 }
+
+    ## work on entry
+
     if ($#oc==0 && $oc[0] eq "top"){
 	
 	# if there is only one objectclass: top
 	# replace with ispmanBranch
-	$msg.="replacing objectclass \"top\" with \"ispmanBranch\"\n";
-	$entry->replace("objectclass", "ispmanBranch");
+	$msg.="replacing objectclass: \"top\" -> \"ispmanBranch\"\n";
+	ldif_action("replace","objectclass","ispmanbranch");
 
-    } elsif ($dn=~m/^ou=/){
+    } elsif ($dn=~m/^ou=/ && $oc[0] ne "ispmanBranch"){
 
 	# if entry starts with "ou=" replace 
-	# objectclasses top, organizationalunit with ispmanBranch
-	$msg.="replacing objectclass with \"ispmanBranch\"\n";
-	$entry->replace("objectclass", "ispmanBranch");
+       	# objectclasses top, organizationalunit with ispmanBranch
+	$msg.="replacing objectclass: -> \"ispmanBranch\"\n";
+	ldif_action("replace","objectclass","ispmanbranch");
 
-    } elsif ($dn=~m/^ispmanDomain=/){
+    } elsif ($oc{"ispmanDomain"}){
 	
 	# update ispmanDomain objectclasses
 	if ($entry->get_value("ispmanDomainType") eq "replica") {
-	    $msg.="Found ispmanReplicaDomain:\n";
-	    $msg.="replacing objectclass with [@oc_replicaDomain]\n";
-	    $entry->replace("objectclass", @oc_replicaDomain );
+	    $msg.=update_oc($entry,\@oc,\@oc_replicaDomain);
 	} else {
-	    $msg.="Found ispmanDomain:\n";
-	    $msg.="replacing objectclass with [@oc_normalDomain]\n";
-	    $entry->replace("objectclass", @oc_normalDomain);
+	    $msg.=update_oc($entry,\@oc,\@oc_normalDomain);
 	}
 
 	# check ispmanDomainDefaultFileServer attribute
 	if (! defined $entry->get_value("ispmanDomainDefaultFileServer")){
 	    $msg.="WARNING! no \"Default Fileserver\" defined!\n";
 	    foreach (@default_fileserver){
-		$msg.="adding ispmanDomainDefaultFileServer with \"$_\"\n";
-		$entry->add("ispmanDomainDefaultFileServer",$_);
+		$msg.="adding ispmanDomainDefaultFileServer: \"$_\"\n";
+		ldif_action("add","ispmanDomainDefaultFileServer",$_);
 	    }
 	}
 
@@ -115,68 +191,83 @@
 	if (! defined $entry->get_value("ispmanDomainDefaultWebHost")){
 	    $msg.="WARNING! no \"Default Webhost\" defined!\n";
 	    foreach (@default_webhost){
-		$msg.="adding ispmanDomainWebHost with \"$_\"\n";
-		$entry->add("ispmanDomainDefaultWebHost",$_);
+		$msg.="adding ispmanDomainWebHost: \"$_\"\n";
+		ldif_action("add","ispmanDomainDefaultWebHost",$_);
 	    }
 	}
 
-    } elsif ($dn=~m/^ispmanVhostName/){
+    } elsif ($oc{'ispmanVirtualHost'}){
 
 	# update ispmanVhost
-	$msg.="Found ispmanVhost:\n";
 	my $ispmanDomain=$entry->get_value("ispmanDomain") || die("ispmanDomain undefined!");
     	my $ispmanVhostName=$entry->get_value("ispmanVhostName") || die("ispmanVhostName undefined!");
 
-	# replacing vhost objectclasses
-	$msg.="replacing objectclass with [@oc_virtualHost]\n";
-	$entry->replace("objectclass", @oc_virtualHost);
-	
+	# checking/replacing vhost objectclasses
+	$msg.=update_oc($entry,\@oc,\@oc_virtualHost);
+
 	# checking vhost cn attribute
+	my $lcn=$entry->get_value("cn");
 	my $cn=join ".", ($ispmanVhostName, $ispmanDomain);
-	if (! defined ($entry->get_value("cn"))){
+	if (! defined $lcn){
 	    $msg.="adding cn with \"$cn\"\n";
-	    $entry->add("cn", $cn);
-	} elsif ($entry->get_value("cn") ne $ispmanVhostName) {
-	    $msg.="changing cn to \"$cn\"\n";
-	    $entry->replace("cn", $cn);
+	    ldif_action("add","cn",$cn);
+	} elsif ($lcn ne $cn) {
+	    $msg.="changing cn: \"$lcn\" -> \"$cn\"\n";
+	    ldif_action("replace","cn",$cn);
 	}
 	
 	# checking vhost uid attribute
+	my $luid=$entry->get_value("uid");
 	my $uid=join ".", ($ispmanVhostName, $ispmanDomain);
-	if (! defined ($entry->get_value("uid"))){
+	if (! defined $luid){
 	    $msg.="adding uid with \"$uid\"\n";
-	    $entry->add("uid", $uid);
-	} elsif ($entry->get_value("uid") ne $uid){
-	    $msg.="changing uid to \"$uid\"\n";
-	    $entry->replace("uid", $uid);
+	    ldif_action("add","uid",$uid);
+	} elsif ($luid ne $uid){
+	    $msg.="changing uid: \"$luid\" -> \"$uid\"\n";
+	    ldif_action("replace","uid",$uid);
 	}
 	
 	# checking vhost uidNumber attribute
 	unless ($entry->get_value("uidNumber")){
-	    $msg.="adding dummy uidNumber: $dummyUid. This should be replaced later!\n";
-	    $entry->add("uidNumber", $dummyUid);
+	    $msg.="adding dummy uidNumber: $dummyUid (This should be replaced later!\n)";
+	    ldif_action("add","uidNumber",$dummyUid);
 	}
 
 	# checking vhost gidNumber attribute
 	unless ($entry->get_value("gidNumber")){
-	    $msg.="adding dummy gidNumber: $dummyGid. This should be replaced later!\n";
-	    $entry->add("gidNumber", $dummyGid);
+	    $msg.="adding dummy gidNumber: $dummyGid (This should be replaced later!)\n";
+	    ldif_action("add","gidNumber",$dummyGid);
 	}
 
 	# checking vhost homeDirectory attribute
 	my $homedir=join '/', ($default_domainHomedir, $ispmanDomain, 'vhosts',
 			       $ispmanVhostName);
 	unless ($entry->get_value("homeDirectory")){
-	    $msg.="adding homeDirectory with \"$homedir\"\n";
-	    $entry->add("homeDirectory", $homedir);
+	    $msg.="adding homeDirectory: \"$homedir\"\n";
+	    ldif_action("add","homeDirectory",$homedir);
 	}
         
 	# checking vhost userPassword attribute
 	unless ($entry->get_value("userPassword")){
-	    $msg.="adding userPassword with \"$dummyPassword\". This should be replaced later!\n";
-	    $entry->add("userPassword", $dummyPassword);
+	    $msg.="adding userPassword: \"$dummyPassword\" (This should be replaced later!)\n";
+	    ldif_action("add","userPassword",$dummyPassword);
 	}
 	
+    } elsif ($oc{'ispmanDomainUser'}){
+	
+	# checking for alternate uid
+	my @uids=$entry->get_value("uid");
+	my $uid=join "@", $entry->get_value("ispmanUserId"),
+	                  $entry->get_value("ispmanDomain");
+	my $hasAlternateUid=0;
+	for (@uids) {
+	    if ($_ eq $uid) { $hasAlternateUid=1; }
+	}
+	if (! $hasAlternateUid) {
+	    $msg.="adding uid: \"$uid\"\n";
+	    ldif_action("add","uid",$uid);
+	}
+
     } else {
 	# check other entries here	
 	
@@ -193,7 +284,7 @@
     }
     if (! $found) {
 	$msg.="adding RDN to attributes ($attrib: $attribval)\n";
-	$entry->add($attrib,$attribval);
+	ldif_action("add",$attrib,$attribval);
     }
 
     # output msg
@@ -206,12 +297,24 @@
     #print $entry->dump(), "\n";
     #$entry->dump();
 
-    # write changed ldif
-    $ldif2->write_entry($entry);
+    # write changed entry
+    if ($mode eq "add"){
+	$ldif_out->write_entry($entry);
+    } elsif ($chng) {
+	print OUTLDIF "dn: $dn\n";
+	print OUTLDIF "changetype: modify\n";
+	print OUTLDIF $chng;
+	print OUTLDIF "\n";
+    }
 }
 
-$ldif->done();
-$ldif2->done();
+$ldif_in->done();
+
+if ($mode eq "add"){
+    $ldif_out->done();
+} else {
+    close(OUTLDIF);
+}
 
 
 



-------------------------------------------------------
The SF.Net email is sponsored by EclipseCon 2004
Premiere Conference on Open Tools Development and Integration
See the breadth of Eclipse activity. February 3-5 in Anaheim, CA.
http://www.eclipsecon.org/osdn
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.