Try this. It generates a file that could be used to import contacts into zimbra. You'll need to define some ldap variables below. Test it out and make sure it is something you can use.
Code:#! /usr/bin/perl # # [Name] # imsPAB2zimbra.pl # # [Description] # This script exports an individual's iplanet messaging server PAB # and converts the export into a form usable by zimbra's zmmailbox tool. # Tested against ims5.2. # # It runs an ldapsearch to locate a user's pab entries # and convert them into a format usable to zmmailbox # # [Synopsis] # - convert the ldap pab into cct commands for importing # imsPAB2zimbra.pl jimnorton > results.txt # # [ Importing ] # import the pab using zimbra's zmmailbox command. # zimbra@host# zmmailbox -z -m jimnorton@host.com -f ./results.txt # # [Other useful commands] # - Get all the existing contacts # zimbra@host# zmmailbox -z -m jimnorton@host.com gact # # - Delete all existing zimbra contacts from given user # It is recommended this step be skipped!!!! # zimbra@host# zmmailbox -z -m jimnorton@host.com ef /Contacts # # ASSUMPTIONS: # 1. User's DN and PAB entries are on the same directory server. # If not, then additional tooling is required. This script # uses the user's pabURI value to locate their PAB entries. # # # # JF - 20090308 # use Net::LDAP; ######################################################################## # Directory server settings # Description: The user's pabURI is used to locate their PAB # - Define the following ######################################################################## my $ldapHost = 'ldapserver.somehost.com'; my $ldapPort = '389'; my $ldapBind = 'cn=directory manager'; my $ldapPass = 'xxxxxxx'; my $ldapBaseDN = 'o=ABC Corp,dc=somehost,dc=com'; # where you expect to find the user's DN my $ldapScope = 'sub'; ######################################################################## # iplanet attribute => zimbra attr my %sun2zimPerson = ( 'cn' => 'fullName', 'givenname' => 'firstName', 'sn' => 'lastName', 'mail' => 'email', 'telephonenumber' => 'workPhone', 'mobile' => 'mobilePhone', 'pager' => 'pager', 'facsimiletelephonenumber' => 'workFax', 'street' => 'workStreet', 'l' => 'workCity', 'st' => 'workState', 'postalcode' => 'workPostalCode', 'co' => 'workCountry', 'dateofbirth' => 'birthday', 'labeleduri' => 'workURL', 'description' => 'notes' ); my $uid = shift or die "$0 <uid>\n"; # The iPlanet PAB is converted into a file that can be imported into Zimbra. # This file is locate here: my $output = '/tmp/' . $uid . '.import'; # connect and locate the user's paburi my $ldap = Net::LDAP->new( $ldapHost, port => $ldapPort ) or die "$@"; my $mesg = $ldap->bind( $ldapBind, password => $ldapPass ) or die $!; my $res = $ldap->search( base => $ldapBaseDN, scope => 'sub', filter => '(uid=' . $uid . ')', attrs => ['paburi']); $res->code && die $res->error; $res->count != 1 && die "More than one result returned\n"; my $paburi = $res->entry(0)->get_value('paburi'); ####################################################################### # BIG assumption ... PAB is on the same directory server. # # If the directory server is somewhere else, clean up # this connection and reconnect to the appropriate server ####################################################################### if( $paburi =~ /ldap:\/\/.*?\/(.*)/){ $ldapBaseDN = $1; } else { die "The directory entry contained no pabURI for $uid\n"; } # Next, search for all the PAB entries for this user my $res = $ldap->search(base => $ldapBaseDN, scope => 'sub', filter => '(objectclass=*)'); $res->code && die $res->error; # cycle through the PAB and build a HoHs foreach $ent ($res->entries) { $key = $ent->get_value('un'); $key or next; @obj = $ent->get_value('objectclass'); foreach $val (@obj){ $val = lc $val; if( ($val eq 'pabgroup') || ($val eq 'pabperson') ) { $val =~ s/^\'|\'$//; $entry{$key}{'objectclass'} = $val; } } @mem = $ent->get_value('memberofpabgroup'); foreach $val (@mem){ push @{ $entry{$key}{'memberofpabgroup'} }, $val; push @{ $entry{$val}{'members'} }, $key; } foreach $i ( keys %sun2zimPerson ){ $val = $ent->get_value($i); $val =~ s/\$/"\n"/eg; $val =~ s/\\(..)/pack'H*',$1/eg; $entry{$key}{$i} = $val; } } $ldap->unbind; open OUT, "> $output" or die $!; foreach $key ( keys %entry ){ $line = ''; # if it isn't a person or group skip it if( $entry{$key}{'objectclass'} eq 'pabgroup' ){ $entry{$key}{'cn'} or next; # if no group name, skip it. $entry{$key}{'cn'} =~ s/\"/\\"/sg; $entry{$key}{'cn'} =~ s/^\'|\'$//; $entry{$key}{'cn'} =~ s/^\s+|\s+$//; print OUT "cct type group nickname \"$entry{$key}{'cn'}\" fileAs \"8:$entry{$key}{'cn'}\" "; $line = ''; # this pulls the list members for $i ( @{ $entry{$key}{'members'} } ){ if($entry{$i}{'cn'}) { $_ = $entry{$i}{'cn'}; s/\"/\\"/sg; s/^\'|\'$//; # no leading or trailing single quotes s/^\s+|\s+$//; # no leading or trailing spaces $line .= "$_ "; } if( $entry{$i}{'mail'} =~ /\@/ ) # buggy if it doesn't contain an @ { $entry{$key}{$i} =~ s/^\s+|\s+$//; $line .= "<$entry{$i}{'mail'}>,"; } } $line =~ s/^(.*?).$/dlist \"$1\"/; # drop last comma and adds the list command print OUT $line . "\n"; } elsif( $entry{$key}{'objectclass'} eq 'pabperson' ){ print OUT "cct "; for $i (keys %sun2zimPerson){ if( $entry{$key}{$i} ) { $entry{$key}{$i} =~ s/\"/\\"/sg; $entry{$key}{$i} =~ s/^\'|\'$//; $entry{$key}{$i} =~ s/^\s+|\s+$//; if($entry{$key}{$i} =~ /\n|\s|,/s) { $entry{$key}{$i} =~ s/^(.*)$/\"$1\"/msg; } $entry{$key}{$i} =~ s/\n/\\n/msg; print OUT "$sun2zimPerson{$i} $entry{$key}{$i} "; } } print OUT "\n"; } } print "Now run:\n zmmailbox -z -m uid\@domain -f $output\n" . "like, " . " zmmailbox -z -m jimnorton\@host.com -f $output\n";
Thx
I'll test it and let you know how it goes.
BR.
It works just fine.
Now I guess I have to try to adapt it to bulk export users' PABs from Sunone Directory Server and import them into zimbra.
Thx a lot.
Hi fowler,
Just a FYI.
Since we are using hosted domains in JES, I had to do a minor change in your script to do the search based on the mail attribute, or else it was giving a "More than one result returned" error when it finds a username that exists in more than one domain:
instead ofCode:my $uid = shift or die "$0 <mail>\n";andmy $uid = shift or die "$0 <uid>\n";
instead ofCode:my $res = $ldap->search( base => $ldapBaseDN, scope => 'sub', filter => '(mail=' . $uid . ')', attrs => ['paburi']);Everything else worked like a charm.my $res = $ldap->search( base => $ldapBaseDN, scope => 'sub', filter => '(uid=' . $uid . ')', attrs => ['paburi']);
Thanks again
Cheers
Very cool. Glad you could make use of it!
Can you please PM me he perl script?
How can I check the userpassword is {CRYT} or {SSHA} from iPlanet?
If I use eDirectory to replace iPlanet, then all JMS user login / out by using eDirectory,during migration, can I use eDirectory and no need to key in the password or reset the password? Please advise.
The script is posted in this thread. It is specific for iPlanet Messaging server for the purpose of migrating contacts into Zimbra. If you are attempting something else, it may not be very helpful.
try using ldapsearch from the command line.How can I check the userpassword is {CRYT} or {SSHA} from iPlanet?
You will probably have better luck in another forum geared toward edirectory migrations.If I use eDirectory to replace iPlanet, then all JMS user login / out by using eDirectory,during migration, can I use eDirectory and no need to key in the password or reset the password? Please advise.
There are currently 1 users browsing this thread. (0 members and 1 guests)