Importing Contacts from Thunderbird Addressbook into LDAP

1) As described in the previous post – Setting up LDAP (slapd) on Mac OS X (non-server edition) – you need to download mozillaOrgPerson.schema and reference it on slapd.conf. This page describes the process:

http://applications.linux.com/applications/05/05/18/1248224.shtml?tid=37

along with the following instructions

2) Before you do an export, I would advise creating a dummy contact in your address book, and filling in every field with a message that echoes that field’s name – for instance First Name: “myFirstName”, Last Name: “myLastName” etc, etc. This will make it much easier to map fields to names for troubleshooting later. Don’t put non-numeric characters in phone number fields though, since this will cause import errors in LDAP (ask me how I know…)

Now export the Thunderbird address book as an ldif file (open Thunderbird, then go “Tools->export”), and use this perl script (instead of the one on the above-linked page) to convert the ldif export file to the correct format. Note you need to edit either the script or your input filename so they match, and you need to edit the script to add your domain name:

==========================================================

#!/usr/bin/perl -pi
# Perl script to convert my LDIFs from Mozilla into a format which
# can be imported successfully into OpenLDAP, using the Moz v0.6
# schema.
# Johny Agotnes (mozilla@agotnes.com) – June 2003
use MIME::Base64;

# Variables to change block
# Handle the different dn strings

### NEED TO EDIT THIS ###
$dnVariable = “ou=addressbook, dc=my-domain, dc=com”;
### NEED TO EDIT THIS ###

### NEED TO EDIT THIS ###
$inPutFile = “ThunderbirdAddressBook.ldif” ;
### NEED TO EDIT THIS ###

# END of Variables to change block

if ( ! open(MYINPUTFILE, $inPutFile)) {
print (”File < ” . $inPutFile . “> not found!”) ;
exit 1 ;
} ;

while(<myinputfile>)
{
# Good practice to store $_ value because
# subsequent operations may change it.
my($line) = $_;

# Good practice to always strip the trailing
# newline from the line, change from DOS eol first.
# $line =~ s/.$// ;
chomp($line);

# ‘dn’ handling, ick ick, it seems :: indicates base64 encoding
if ($line =~ /^dn::/) {
# Strip off the ‘dn:: ‘ part so that decode_base64 will work
$line =~ s/^dn:: //;
$line = decode_base64($line) ;
$line = cleanDN($line) ;
# Second param to stop linebreaks
$line = encode_base64($line, “”) ;

# Prepend ‘dn:: ‘ to make it correct again
$line = “dn:: ” . $line ;
# encode_base64 adds a newline, so we get rid of it again.
chomp($line) ;
} elsif ( $line =~ /^dn:/) {
$line = cleanDN($line) ;
}

# Correct Syntactic Export errors
$line =~ s/mozillaAbPersonObsolete/mozillaOrgPerson/;
$line =~ s/^modifytimestamp.*$/doNotPrintThisLine/ ;
$line =~ s/^xmozillanickname.*$/doNotPrintThisLine/ ;
$line =~ s/workurl/mozillaWorkUrl/;

# Start Black Magic
# If no sn, set sn from org name
$done = 0 ;
if ((/^dn:/…/^o:/) && ($done==0) ){
goto Cont if /^sn:/;
goto Replcn if /cn:/;
goto Repl if /o:/;
goto nada ;
Cont:
$done=1; goto nada;
Replcn:
my($line) = $_;

# $line =~ s/.$// ;
$line =~ s/cn:/sn:/;
print $line ;
$done=1; goto nada;
Repl:
my($line) = $_;
# $line =~ s/.$// ;
$line =~ s/o:/sn:/;
print $line ;
nada:
}
if (/^$/) {
$done = 0 ;
}
# End Black Magic

# Print the line to the screen and add a newline if we’re not
# told not to by the contents of the line
if ($line ne “doNotPrintThisLine” ) {
print “$linen”;
}
}

sub cleanDN
{
# Surely there are better ways of doing this for subroutines?
my $dnString = $_[0] ;
$dnString =~ s/,mail.*$//;
$dnString =~ s/,*//;
$dnString =~ s/.*$/$&, $dnVariable/;

return $dnString ;
}

==========================================================

I got this file from Mozilla’s site – it was an attachment to a bugzilla bug (#116692) – but note that I had to edit it to get the correct output for my setup. I think that to actually run it, I had to redirect its output to a file, something like:
pt.pl > outputfile.ldif
- otherwise it sent its output to stdout.

This didn’t get rid of commas within the fields (for example – Dr A Jones, MD) – which mess up the import – so I manually did a search & replace on all commas after I ran the above perl script. I know perl does this kind of thing in its sleep, but I despise perl, and didn’t want to spend more time than necessary debugging it, so I just fired up my favorite editor…

Follow the instructions on the above-linked page to complete the import into LDAP. Other import errors I had included the presence of non-numeric values in phone # fields. Just edit by hand and start again. Tedious, but it works eventually.

I found phpLDAPAdmin (http://phpldapadmin.sourceforge.net/) invaluable – just drop it in your /Library/Webserver/Documents directory, edit the config file to point it at your server, edit your httpd.conf file to enable php (basically uncomment all the lines that mention using php), then restart Apache, and away you go

THUNDERBIRD TWEAKS REQUIRED:

Some of The LDAP field names that Thunderbird uses in its exported contacts are different from the ones that the addressbook actually looks for when connectign to an LDAP server – pretty frustrating. Anyway, if you do the following, all shoudl be well:

Download Thunderbird 1.5beta1 from:

http://www.mozilla.org/products/thunderbird/releases/1.5beta1.html

older versions do not have the ldap mappings in the preferences

—————————-

After installing it and firing it up, look under preferences (or Tools -> Options on windows), go to advanced and select “general” tab, then click “Config Editor” button.
In config editor, change these existing keys to the values shown:

ldap_2.servers.default.attrmap.HomeAddress -> mozillaHomeStreet,homePostalAddress
ldap_2.servers.default.attrmap.HomeAddress2 -> mozillaHomeStreet2,mozillaHomePostalAddress2
ldap_2.servers.default.attrmap.WorkAddress -> street,streetaddress,postOfficeBox,postalAddress
ldap_2.servers.default.attrmap.WorkAddress2 -> mozillaWorkStreet2,mozillaPostalAddress2

These will ensure that the first and second lines of the home address and work address appear as they should.

Next, make this change:

ldap_2.autoComplete.directoryServer -> ldap_2.servers.myLDAPserver

(where “myLDAPserver” should be changed to the name of your ldap server, AS DEFINED IN THE PREFERENCS ENTRIES, under ldap_2.servers.***)

This will make thunderbird do an LDAP lookup to autocomplete any email addresses or names you are typing in the To: Cc: or Bcc: fields of new emails – fantastic!

restart thunderbird, and enjoy!

=======================================================

In case anyone has problems connecting to the LDAP server with their username/bind address and password – I found this useful info in a discussion archive at http://www.openldap.org/lists/openldap-software/200301/msg00715.html

CONNECTION TIP – SASL vs SIMPLE

> Seems something wrong with my slapd instance. (Maybe the setup process
> wasn’t completed.) It always report,
> /SASL [conn=0] Error: unable to open Berkeley db /etc/sasldb2: No such
> file or directory/
> Then I touch a file /etc/sasldb2 but of cause it didn’t work.

I note that the ldapadd command you use is not using the right set of
flags for SASL bind. If you want to use SASL you need to specify
‘-U <username>’ rather than ‘-D <binddn>’. If you do not want SASL
then you need ‘-W -x’.

Assuming you want SASL…

This seems rather important:

> additional info: SASL(-13): user not found: no secret in database

If you want to use SASL bind then you need some SASL secrets for the
user concerned. SLAPD cannot update the SASL database – it must be
done by other means.

Try this as root:

saslpasswd2 -c <username>

where <username> is the SASL username that you want to create. There
is no connection with Unix usernames.

Then make sure that /etc/sasldb2 is non-zero and is readable by the
user that slapd runs as. It should not be globally readable, as SASL
secrets are effectively stored in clear.

With 2.1.x versions it is possible to store SASL secrets in the
directory itself. See section 10.2 of the manual for details.

=======================================================

Post a Comment