Connect. Communicate. Collaborate. Securely.

Home » Kerio User Forums » Kerio Connect » Exporting All Public (Contact) Folders to LDIF for merge with LDAP
  •  
nickrooster

Messages: 88
Karma: 0
Send a private message to this user
Hello,
I was wondering if it were possible to export all of our contacts to an LDIF which can be read by openldap?
We are looking to set up a LDAP server in order to have web apps be able to reference our large contact database, and also allow Thunderbird to easily search contacts. (Currently, in Thunderbird, you must go to address book, choose the Kerio LDAP server, do an advanced find, change the option to "Match All of the Following", change the second drop down to begins with, and then you can search). With a regular LDAP server, we can search in Thunderbird as much as we want, and as easily (in the sidebar, etc.).
So...
has anyone done this? Do you have any tips for me? I have looked into the directory which stores the data for the contacts, hoping to find vCard files, but found .emls. It looks like they actually contain vCards, so I might copy that whole directory and try changing them to ldifs with an automated program, but looking for an easier way, perhaps with one giant LDIF as the output?
Help Appreciated!!
-Nick

[Updated on: Tue, 24 May 2005 15:40]

  •  
nickrooster

Messages: 88
Karma: 0
Send a private message to this user
Well, I found out a little about Kerio's LDAP in the past couple of days...
The reason why it cannot search contacts in the sidebar is that it is matching any part of the contact with the string you input with a regexp (*.nick.*)
When you do an advanced find it uses a different regexp (^nick.*) to search only the beginning of the contact for the input string.

Very strange. I am going to work on an extension to Thunderbird to change the sidebar's behavior. Also, I have found a Perl script to convert between the two. I had to modify it to accept Kerio's vCard files, but it works. Reply to this if you would like the script...
Thanks,
-Nick
  •  
DonaldNewlands

Messages: 12
Karma: 0
Send a private message to this user
Hi Nick,

Thanks for the information.

Please do post your conversion Perl script. :)

Also, which LDAP server are you using?

-Donald
  •  
nickrooster

Messages: 88
Karma: 0
Send a private message to this user
I am using OpenLDAP 2.1.29-1

Andreas Neustifter is the person who created this script and released it under the GPL, and I have modified it to work with Kerio's vCard format.
To make this script work for you, open up a bash prompt and copy /opt/kerio/mailserver/store/#public [folder of your choice].
Then I went through each phone book and made a for loop to change the prefix to designate which phone book they were from - repeat as necessary.
Next, I made a new directory to hold ALL of the contacts with the prefix added, made another for loop that cats the vCards and puts them (>) in allcontacts.vcf
Then run the script allcontacts.vcf > allcontacts.ldif

There are still two problems with this script -
1) It does not grab Fax Numbers for some reason... still working on that
2) I still have not successfully imported the ldif that is generated into openLDAP, but that is mostly a time constraint problem rather than a fault with the output.

Kerio has told me their LDAP issue would be fixed with 6.1. Donald, are you running 6.1? I am now trying to find out if this issue has been fixed before I start really source-diving to break Thunderbird in the way Kerio likes (j/k) ;)

#!/usr/bin/perl
###################################################################################################
# released by Andreas Neustifter under the GPL
# see COPYING for Details about the GPL
###################################################################################################
use strict;
                                                                                
###################################################################################################
# variable definitions
my $version="0.6.2";
my $exit;
my $debug;
my $mapping=0;
my $inside = 0;
my $change_names = 0;
                                                                                
my $line;
my <_at_>line;
my <_at_>data;
my <_at_>tag;
                                                                                
my ($cn,$givenname,$sn,$nickname,$mail,$mail2,$screenname,$htmlmail,$workphone,$homephone,$fax);
my ($pager,$mobile,$homeaddress1,$homeaddress2,$homecity,$homestate,$homezip,$homecountry,$workaddress1);
my ($workaddress2,$workcity,$workstate,$workzip,$workcountry,$worktitle,$workdep,$workorg);
my ($workurl,$homeurl,$custom1,$custom2,$custom3,$custom4,$notes,$uid);
                                                                                
###################################################################################################
# main part
attributes();
                                                                                
($debug) && printf(STDERR "starting operation\n");
                                                                                
while (<>) {
    # prepare line
    s/type=/TYPE=/;
    $line = $_;
    if ( $line =~ /\015/ ) { $line = (split(/\015/,$line))[0]; }
                                                                                
    # if line is the begin of a vcard mark that we are inside a card
    if ( ( $line =~ /BEGIN:VCARD/i ) && ( $inside == 0 ) ) {
        $inside = 1;
        ($debug) && printf(STDERR "begin of vcard found\n");
    }
    # if line is the end of a vcard, print the values to a ldif, clear the vars and mark that we
    # are outside again
    if ( ( $line =~ /END:VCARD/ ) && ( $inside == 1 ) ) {
        print_ldif();
        clear_vars();
        $inside = 0;
        ($debug) && printf(STDERR "end of vcard found\n");
    }
    # if we are inside a vcard, convert the line
    if ( $inside == 1 ) {
        read_vcard();
    }
}
                                                                                
###################################################################################################
# reads one vcard line and converts it
sub read_vcard {
                                                                                
# convert the line to nice accessible tag and data array
<_at_>line = ($line =~ /([^:]*:)(.*)/);
<_at_>data = split(/;/,<_at_>line[1]);
<_at_>tag = split(/;/,<_at_>line[0]);
                                                                                
if ( <_at_>line[0] =~ /^URL:/ ) { $homeurl = <_at_>data[0] };
if ( <_at_>tag[0] =~ /TITLE/ ) { $worktitle = <_at_>data[0] };
if ( <_at_>tag[0] =~ /ORG/ ) {
    $workorg = <_at_>data[0];
    $workdep = <_at_>data[1];
}
if ( <_at_>tag[0] =~ /NICKNAME/ ) { $nickname = <_at_>data[0] };
if ( <_at_>tag[0] =~ /NOTE/ ) { $notes = <_at_>data[0] };
if ( <_at_>tag[0] =~ /UID/ ) { $uid = <_at_>data[0]; }
if ( <_at_>line[0] =~ /^N:/ ) {
    $sn = <_at_>data[0];
    $givenname = <_at_>data[1];
}
if ( <_at_>tag[0] =~ /X-FILE-AS/ ) {
    <_at_>data = split(/\, /,<_at_>data[0]);
    if ( $change_names == 0 ) {
        $cn = <_at_>data[0].", ".<_at_>data[1];
    } else {
        $cn = <_at_>data[1]." ".<_at_>data[0];
    }
}
if ( <_at_>tag[0] =~ /X-MOZILLA-HTML/ ) { $htmlmail = <_at_>data[0] };
if ( <_at_>tag[0] =~ /EMAIL/ ) {
    if ( <_at_>tag[1] =~ /TYPE=pref/ ) {
        $mail = <_at_>data[0];
    } elsif ( <_at_>tag[1] =~ /TYPE=HOME/ ) {
        $mail = <_at_>data[0];
    } elsif ( <_at_>tag[1] =~ /TYPE=WORK/ ) {
        $mail2 = <_at_>data[0];
    } elsif ( <_at_>tag[1] =~ /TYPE=INTERNET/ ) {
        $mail2 = $mail; $mail=<_at_>data[0];
    } elsif ( <_at_>tag[1] =~ /TYPE=OTHER/ ) {
        $mail2 = $mail; $mail=<_at_>data[0];
    } else {
        $mail = <_at_>data[0];
    }
}
if ( <_at_>tag[0] =~ /TEL/ ) {
    if ( <_at_>tag[1] =~ /TYPE=HOME/ ) {
        if ( <_at_>tag[2] =~ /TYPE=FAX,WORK/ ) {
            $fax = <_at_>data[0];
        } else {
            $homephone = <_at_>data[0];
        }
    } elsif ( <_at_>tag[1] =~ /TYPE=VOICE,WORK/ ) {
        if ( <_at_>tag[2] =~ /TYPE=FAX,WORK/ ) {
            $fax = <_at_>data[0];
        } else {
            $workphone = <_at_>data[0];
        }
    } elsif ( <_at_>tag[1] =~ /TYPE=CELL/ ) {
        $mobile = <_at_>data[0];
    } elsif ( <_at_>tag[1] =~ /TYPE=PAGER/ ) {
        $pager = <_at_>data[0];
    }
}
if ( ( <_at_>tag[0] =~ /ADR/) && ( <_at_>tag[1] =~ /TYPE=WORK,PREF/ ) ) {
    if ( $mapping == 0 ) {
        $workaddress1 = <_at_>data[2];
        $workaddress2 = <_at_>data[0];
        $workcity = <_at_>data[3];
        $workstate = <_at_>data[4];
        $workzip = <_at_>data[5];
        $workcountry = <_at_>data[6];
    } elsif ( $mapping == 1 ) {
        $workaddress1 = <_at_>data[2];
        $workaddress2 = <_at_>data[1];
        $workaddress2 =~ s/\\n//g;
    }
};
if ( ( <_at_>tag[0] =~ /ADR/ ) && ( <_at_>tag[1] =~ /TYPE=HOME/ ) ) {
    $homeaddress1 = <_at_>data[2];
    $homeaddress2 = <_at_>data[0];
    $homecity = <_at_>data[3];
    $homestate = <_at_>data[4];
    $homezip = <_at_>data[5];
    $homecountry = <_at_>data[6];
};
if ( ( <_at_>tag[0] =~ /X-AIM/ ) && ( <_at_>tag[1] =~ /TYPE=HOME/ ) && ( <_at_>tag[2] =~ /X-UI-SLOT=1/ ) ) { $screenname = <_at_>data[0] };
                                                                                
}
                                                                                
###################################################################################################
# prints the read values to the STDOUT
sub print_ldif {
                                                                                
print "dn: cn=".$givenname." ".$sn."\n" ;
print "objectclass: top\n";
print "objectclass: person\n" ;
print "objectclass: organizationalPerson\n" ;
print "objectclass: inetOrgPerson\n" ;
print "objectclass: mozillaAbPersonObsolete\n" ;
print "givenName: ".$givenname."\n" ;
print "sn: ".$sn."\n" ;
print "cn: ".$cn."\n" ;
print "uid: ".$uid."\n";
print "xmozillanickname: ".$nickname."\n" ;
print "mail: ".$mail."\n" ;
print "mozillaSecondEmail: ".$mail2."\n" ;
print "mozilla_AimScreenName: ".$screenname."\n" ;
print "xmozillausehtmlmail: ".$htmlmail."\n" ;
print "telephoneNumber: ".$workphone."\n" ;
print "homePhone: ".$homephone."\n" ;
print "facsimileTelephoneNumber: ".$fax."\n" ;
print "pager: ".$pager."\n" ;
print "mobile: ".$mobile."\n" ;
print "homePostalAddress: ".$homeaddress1."\n" ;
print "mozillaHomePostalAddress2: ".$homeaddress2."\n" ;
print "mozillaHomeLocalityName: ".$homecity."\n" ;
print "mozillaHomeState: ".$homestate."\n" ;
print "mozillaHomePostalCode: ".$homezip."\n" ;
print "mozillaHomeCountryName: ".$homecountry."\n" ;
print "postalAddress: ".$workaddress1."\n" ;
print "mozillaPostalAddress2: ".$workaddress2."\n" ;
print "l: ".$workcity."\n" ;
print "st: ".$workstate."\n" ;
print "postalCode: ".$workzip."\n" ;
print "c: ".$workcountry."\n" ;
print "title: ".$worktitle."\n" ;
print "ou: ".$workdep."\n" ;
print "o: ".$workorg."\n" ;
print "workurl: ".$workurl."\n" ;
print "homeurl: ".$homeurl."\n" ;
print "custom1: ".$custom1."\n" ;
print "custom2: ".$custom2."\n" ;
print "custom3: ".$custom3."\n" ;
print "custom4: ".$custom4."\n" ;
print "description: ".$notes."\n" ;
print "\n" ;
                                                                                
}
                                                                                
###################################################################################################
# clears the variables where the read values are strored
sub clear_vars {
                                                                                
$cn="";$givenname="";$sn="";$nickname="";$mail="";$mail2="";$screenname="";$htmlmail="";
$workphone="";$homephone="";$fax="";$pager="";$mobile="";$homeaddress1="";
$homeaddress2="";$homecity="";$homestate="";$homezip="";$homecountry="";$workaddress1="";
$workaddress2="";$workcity="";$workstate="";$workzip="";$workcountry="";
$worktitle="";$workdep="";$workorg="";$workurl="";$homeurl="";$custom1="";$custom2="";$custom3="";$custom4="";$notes="";$uid="";
                                                                                
}
                                                                                
###################################################################################################
# do the cmdl parsing, read options, store their values, all that stuff
sub attributes {
                                                                                
while ( <_at_>ARGV > 0 ) {
    if ( ( <_at_>ARGV[0] =~ /-v/ ) || ( <_at_>ARGV[0] =~ /--version/ ) ) {
        print "vcard2ldif ".$version.", Andreas Neustifter, released under the GPL\n";
        shift <_at_>ARGV;
        $exit = 1;
    }
    if ( ( <_at_>ARGV[0] =~ /-h/ ) || ( <_at_>ARGV[0] =~ /--help/ ) ) {
        help_message();
        shift <_at_>ARGV;
        $exit = 1;
    }
    if ( ( <_at_>ARGV[0] =~ /-d/ ) || ( <_at_>ARGV[0] =~ /--debug/ ) ) {
        shift <_at_>ARGV;
        $debug = 1;
    }
    if ( ( <_at_>ARGV[0] =~ /-0/ ) || ( <_at_>ARGV[0] =~ /--zero/ ) ) {
        shift <_at_>ARGV;
        $mapping = 0;
    }
    if ( ( <_at_>ARGV[0] =~ /-1/ ) || ( <_at_>ARGV[0] =~ /--first/ ) ) {
        shift <_at_>ARGV;
        $mapping = 1;
    }
    if ( ( <_at_>ARGV[0] =~ /-c/ ) || ( <_at_>ARGV[0] =~ /--change/ ) ) {
        shift <_at_>ARGV;
        $change_names = 1;
    }
}
( $exit ) && exit;
                                                                                
}
                                                                                
###################################################################################################
# prints the help message
sub help_message {
                                                                                
print "usage: ./vcard2ldif.pl [options]\n";
print "reads from STDIN and exports to STDOUT\n";
print "Options:\n";
print "-v|--version     displays version info\n";
print "-h|--help        displays this help\n";
print "-d|--debug       displays debug output\n";
print "-c|--change      change cn field from \"LastName, FirstName\" to \"FirstName LastName\"\n";
print "                 this apparently changes the \"Display Name\" of Thunderbird.\n";
print "\nAddress Maping (for work address):\n";
print "Since the fields in the ADR data are somewhat not standardized there are\n";
print "several different mappings, the default is:\n\n";
print "-0|--zero        use default mapping\n";
print "Field 1: mozillaPostalAddress2\n";
print "Field 3: postalAddress\n";
print "Field 4: l\n";
print "Field 5: st\n";
print "Field 6: postalCode\n";
print "Field 7: c\n\n";
print "-1|--first       use first non default mapping\n";
print "Field 2: mozillaPostalAddress2\n";
print "Field 3: postalAddress\n";
print "Note: with this mapping all \"\\n\" strings are cut out of field 2.\n";
                                                                                
}




Save the above script as vcard2ldif.pl and you'll be set (at least with perl-5.8.3-18. You might need to modify slightly to achieve proper conversion from your address books (it depends on how you have them set up) but this works perfectly for us (minus the two exceptions above).


See http://www.gnu.org/copyleft/gpl.html that link for the license terms of the GPL.

-Nick
  •  
DonaldNewlands

Messages: 12
Karma: 0
Send a private message to this user
Hi Nick,

Yes, we're running 6.1 b5.

I thought that if Kerio's LDAP doesn't work that well even when its not busted I may as well start with a server that does.

I've been trying to get Mailserver LDAP to work with Thunderbird and Outlook Express, but so far I've got nothing. The clients will authenticate and apparently connect, but I haven't got any results or any useful errors yet.

Thunderbirds Directory Server Properties:
Name: myconnection
Hostname: mail.mydomain.com
Base DN: (blank = *) (find is always greyed out)
Port Number: 389
Bind DN: email<_at_>mydomain.com
SSL: no

Our LDAP server service is running according to the Admin panel, the ports are open through the firewall, and I have a personal "Contacts" folder and a public "Contacts" folder.

-Donald

  •  
nickrooster

Messages: 88
Karma: 0
Send a private message to this user
In Thunderbird, change your Base DN = fn=public,fn=ContactRoot
I don't know anything about the other client you mentioned ;) (other than that its LDAP support is probably minimal, at best.)
  •  
DonaldNewlands

Messages: 12
Karma: 0
Send a private message to this user
Hi Nick,

I have also tried "Base DN = fn=public,fn=ContactRoot"

According to the documentation, Base DN = blank = *, no?

-Donald
  •  
nickrooster

Messages: 88
Karma: 0
Send a private message to this user
On thunderbird on Linux, go to Edit->Preferences
Click composition
Click Edit Directories
Choose the one you have set up and click edit
On the general tab, make sure that (to follow the docs) Base DN has nothing in it.
Click the advanced tab
Make sure that the scope is subtree and the search filter: (objectclass=*)
click OK, OK, and OK
Close and re-open Thunderbird.
Click Write, and start typing in an address that is in your public folder and it should come up in the address line, as long as you have auto-fill in enabled for that address book.
The bug I am referring to is being able to search using the contacts sidebar or just clicking "Address Books" and typing in something.
There nothing should come up for 6.0.10, but in 6.1 it is supposed to have been fixed (might not be in this beta though). Please let me know if you have any more trouble.
Thanks,
-Nick
Previous Topic: Importing Users from AD
Next Topic: Manual move of Spam eMails
Goto Forum:
  


Disclaimer:
Kerio discussion forums are intended for open communication between forum members and may contain information and material posted by members which may be useful in learning about Kerio products. The discussion forums are not intended to provide technical support for any specific product. Any information implied or expressed in the discussion forums is that of the posting member. Kerio is in no way responsible for the information posted in the forums, or its accuracy. Kerio employees may participate in the discussions, but their postings do not represent an offical position of the company on any issues raised or discussed. Kerio reserves the right to monitor and maintain the forums to promote free and accurate exchange of information.

Current Time: Mon Nov 20 14:30:33 CET 2017

Total time taken to generate the page: 0.00487 seconds
.:: Contact :: Home ::.
Powered by: FUDforum 3.0.4.