Skip to main content

using openLDAP for addressbook

By now I have got exhausted answering folks 'Why IndiMail does not have a shared addressbook'

IndiMail is a pure messaging platform. It does not attempt to do things which can be done better by other software like openLDAP etc.

However, things can get bit tricky setting up an address book using openLDAP. This tutorial should make it easy for you to install your own shared address book. The commands below have worked for me on my linux laptop which is proudly powered by Fedora 12. The commands / configuration may slightly vary for your Linux distro / openLDAP version.


Install openldap


% sudo yum install openldap openldap-servers openldap-clients

Configure openldap

You need to start slapd to implement openldap. slapd uses configurion
file /etc/openldap/slapd.conf

The following slapd.conf file contains the basic configurations required to establish a shared address book on a secure network, however there are no access controls yet defined; security is covered later on. The encrypted root password (rootpw) should be substituted where necessary. You can use slappasswd to generate the password

% slappasswd -s secret
{SSHA}gDPX3cS87+B31mAF5zHCGtEJBYSuqrN/


#
# See slapd.conf(5) for details on configuration options.
# This file should NOT be world readable.
#
include /etc/openldap/schema/corba.schema
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/duaconf.schema
include /etc/openldap/schema/dyngroup.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/java.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/openldap.schema
include /etc/openldap/schema/ppolicy.schema
include /etc/openldap/schema/collective.schema

#######################################################################
# ldbm and/or bdb database definitions
#######################################################################

database bdb
suffix "dc=indimail,dc=org"
checkpoint 1024 15
rootdn "cn=Manager,dc=indimail,dc=org"
rootpw {SSHA}gDPX3cS87+B31mAF5zHCGtEJBYSuqrN/
# The database directory MUST exist prior to running slapd AND
# should only be accessible by the slapd and slap tools.
# Mode 700 recommended.
directory /var/lib/ldap

# Sample access control policy:
# Root DSE: allow anyone to read it
# Subschema (sub)entry DSE: allow anyone to read it
# Other DSEs:
# Allow self write access
# Allow authenticated users read access
# Allow anonymous users to authenticate
# Directives needed to implement policy:
# access to dn.base="" by * read
# access to dn.base="cn=Subschema" by * read
# access to *
# by self write
# by users read
# by anonymous auth
#
# if no access controls are present, the default policy
# allows anyone and everyone to read anything but restricts
# updates to rootdn. (e.g., "access to * by * read")
#
# rootdn can always read and write EVERYTHING!

access to dn.subtree="ou=addressbook,dc=indimail,dc=org"
by anonymous auth
by self write
by users read
access to *
by anonymous auth
by self read
by users read

# Indices to maintain for this database
index objectClass eq,pres
#index ou,cn,mail,surname,givenname eq,pres,sub
#index uidNumber,gidNumber,loginShell eq,pres
#index uid,memberUid eq,pres,sub
#index nisMapName,nisMapEntry eq,pres,sub

Make user that /etc/openldap/slapd.conf is owned by ldap and has write permissions for ldap user.

As of now I prefer openldap using slapd.conf and not slapd.d for configuration.

% sudo /bin/rm -r /etc/openldap/slapd.d

slapd Startup

My favourite method happens to be using djb's supervise and hence is one of the core compoment of the IndiMail package

% cat > /tmp/run1
#!/bin/sh
exec /usr/sbin/slapd -u ldap -f /etc/openldap/slapd.conf -d 0 2>&1
cntrl-d

% cat > /tmp/run2
#!/bin/sh
exec /var/indimail/bin/setuidgid qmaill \
/var/indimail/bin/multilog t /var/log/indimail/slapd.389
cntrl-d

# create /service/.slapd.389 so that svscan does not discover this new service yet
% sudo mkdir -p /service/.slapd.389/log
% sudo mv /tmp/run2 /service/.slapd.389/log/run
% sudo mv /tmp/run1 /service/.slapd.389/run
% sudo chmod +x /service/.slapd.389/run /service/.slapd.389/log/run

# rename .slapd.389 to slapd.389 for svscan to discover and start slapd
% sudo mv /service/.slapd.389 /service/slapd.389

% svstat /service/slapd.389
/service/slapd.389/: up (pid 4069) 4 seconds

AddressBook Entries

Information can be imported and exported into an LDAP directory service using the LDAP Data Interchange Format (LDIF) as defined in RFC2849. An LDIF file specifies the contents of a directory entry in a human readable text format, this allows quick manipulation of a file to re-import similar entries into the directory.

Now that the LDAP server has been configured and is running, we can conduct a simple search of the naming context to see our directory information before we start to import our entries.

The "namingContexts" should be similar to the example below.

% ldapsearch -x -b '' -s base '(objectclass=*)' namingContexts
# extended LDIF
#
# LDAPv3
# base <> with scope base
# filter: (objectclass=*)
# requesting: namingContexts

dn:
namingContexts: dc=indimail,dc=org

# search result
search: 2
result: 0 Success

# numResponses: 2
# numEntries: 1

The following LDIF file will create the hierarchical directory service structure that we will be using for indimail's address book. The first entry is that of the base directory and the second entry is for the Manager's (administrator) account. The last two entries are the two organisational units that we will use to store the authorised users (for adding security later) and the address book entries.

The bolded entries should be changed to suit your configuration requirements.

% cat > addressbook.ldif
# Domain entry
dn: dc=indimail,dc=org
o: IndiMail LDAP Server
dc: indimail
objectclass: dcObject
objectclass: organization

# Manager entry
dn: cn=Manager,dc=indimail,dc=org
cn: Manager
objectclass: organizationalRole

# Users
dn: ou=users,dc=indimail,dc=org
ou: users
objectClass: top
objectClass: organizationalUnit

# Addressbook entry
dn: ou=AddressBook,dc=indimail,dc=org
ou: AddressBook
objectClass: top
objectClass: organizationalUnit
cntrl-d

% ldapadd -x -D 'cn=Manager,dc=indimail,dc=org' -W -f addressbook.ldif
Enter LDAP Password:
adding new entry "dc=indimail,dc=org"
adding new entry "cn=Manager,dc=indimail,dc=org"
adding new entry "ou=users,dc=indimail,dc=org"
adding new entry "ou=addressbook,dc=indimail,dc=org"

The following LDAP search is requesting a listing of all entries starting from the base "dc=indimail,dc=org". This should return all of the entries that where added in the previous step.

% ldapsearch -x -b 'dc=indimail,dc=org' '(objectclass=*)'

# indimail.com
dn: dc=indimail,dc=org
objectClass: top
objectClass: dcObject
objectClass: organization
o: Home LDAP Network
dc: indimail

# Manager, indimail.com
dn: cn=Manager,dc=indimail,dc=org
objectClass: organizationalRole
cn: Manager

# users, indimail.com
dn: ou=users,dc=indimail,dc=org
ou: users
objectClass: top
objectClass: organizationalUnit

# addressbook, indimail.com
dn: ou=addressbook,dc=indimail,dc=org
ou: addressbook
objectClass: top
objectClass: organizationalUnit

Now that we have defined and imported our directory scheme, we are able to create user entries to populate the addressbook. The following is a simple example LDIF entry for a contact.

You can gain use slappasswd to generate a user password

% slappasswd -h {MD5} -s manny
{MD5}j+eKwOqr8vR0sN46lo4WXg==

The first line (dn:) designates where about in the directory the entry will belong when its imported, this should be changed to suit your needs.

% cat > newcontact.ldif
dn:uid=mbhangui,ou=addressbook,dc=indimail,dc=org
uid: mbhangui
cn: Manvendra Bhangui
gn: Manvendra
sn: Bhangui
o: Consim Info Pvt. Ltd.
l: Mandaivelli
street: #94 Coconut Republic
st: TN
postalCode: 600028
pager: +91 44 5555 1111
homePhone: +91 44 5555 1234
telephoneNumber: +91 44 5555 1235
facsimileTelephoneNumber: +91 44 5555 1236
mobile: +91 99401xxxxx
mail: m.bhangui@gmail.com
objectClass: top
objectClass: inetOrgPerson
userPassword: {MD5}j+eKwOqr8vR0sN46lo4WXg==
cntrl-d

The contents of the LDIF file can be added into the directory service using the "ldapadd" command below.

% ldapadd -x -D 'cn=Manager,dc=indimail,dc=org' -W -f newcontact.ldif
Enter LDAP Password:
adding new entry "uid=mbhangui,ou=addressbook,dc=indimail,dc=org"

If you do not require an address book and just require a basic user object to use for authenticaton, a basic user object can be created and imported into the LDAP server. This file uses the "UID" (User ID) string to distinguish the object and the contents are all that we need to create a basic authentication mechanism.

It should also be noted that this object is stored in the "users" organisational unit, which is located outside of the address book directory.=

% cat > useraccount.ldif
dn:uid=postmaster,ou=users,dc=indimail,dc=org
uid: postmaster
userPassword: {MD5}j+eKwOqr8vR0sN46lo4WXg==
objectClass: top
objectClass: account
objectClass: simpleSecurityObject
cntrl-d

% ldapadd -x -D 'cn=Manager,dc=indimail,dc=org' -W -f useraccount.ldif
Enter LDAP Password:
adding new entry "uid=postmaster,ou=users,dc=indimail,dc=org"

For mbhangui to authenticate to the server, one needs to pass
"uid=mbhangui,ou=users,dc=indimail,dc=org" as username along with the the plain text value of password, the hashed value is only for storage purposes.

% ldapsearch -x -b 'ou=AddressBook,dc=indimail,dc=org' \
-D "uid=mbhangui,ou=users,dc=indimail,dc=org" '(objectclass=*)' \
-s sub -w manny

Backing up LDAP Database

To export
% sudo /var/indimail/bin/svc -d /service/slapd.389
% slapcat -vl /etc/openldap/backup_slapd.ldif
% sudo /var/indimail/bin/svc -u /service/slapd.389

To import
% sudo /var/indimail/bin/svc -d /service/slapd.389
% slapadd -vl /etc/openldap/backup_slapd.ldif
% chown ldap.ldap /var/lib/ldap/*
% sudo /var/indimail/bin/svc -u /service/slapd.389

Email Client Settings

The last steps in setting up the shared address book is to configure the users email clients to access the LDAP server.

The following table contains some of the information needed to configure the client applications. Note the username will need to be written as the complete "distinguished name" value so the server knows which object to authenticate.

LDAP Server : your_host_IP:389
Search Base : ou=addressbook,dc=indimail,dc=org
Login Method : use distinguished name (if listed)
Username : uid=user,ou=addressbook,dc=indimail,dc=org
Password : As entered in newcontact.ldif file (plain text version)
Secure Connection: Never (unless encryption has been configured)

In the above 'user' is the actual user created in ldap by using ldapadd

References
  1. http://www.brennan.id.au/20-Shared_Address_Book_LDAP.html
  2. http://www.wains.be/mirrors/feldt.com/
  3. http://linsec.ca/Using_OpenLDAP_as_an_Address_Book

21 comments

Popular posts from this blog

IndiMail Installation for newbies in < 10 steps

Installing Indimail using YUM/APT Repository Install OS
OpenSUSE
openSUSE Leap 42.3
openSUSE Leap 42.2
openSUSE 13.2
openSUSE 13.1
SUSE Linux Enterprise 12 SP2
SUSE Linux Enterprise 12 SP1
SUSE Linux Enterprise 12
Red Hat
Feodra 27
Fedora 26
Red Hat Enterprise Linux 7
Red Hat Enterprise Linux 6
CentOS 7
CentOS 6
Debian
Debian 8.0
Debian 7.0
Ubuntu 17.04
Ubuntu 16.10
Ubuntu 16.04
Ubuntu 14.04
Ubuntu 12.04
Click the below URL for Install Instructions
https://software.opensuse.org/download.html?project=home%3Aindimail&package=indimail Shutdown MySQL if already running and disable MySQL from being started up by the system % /etc/init.d/mysqld stop % sudo chkconfig mysqld off % /bin/rm -f /service/mysql.3306/down
Start IndiMail
% sudo service indimail start Check Servicess
% sudo /usr/bin/svstat /service/* /service/clamd: up (pid 1014) 2985 seconds /service/dnscache: up (pid 1021) 2985 seconds /service/fetchmail: down 2985 seconds /service/freshclam: up (pid 1020) 2…

Using Docker Engine to Run IndiMail / IndiMail-MTA

IndiMail now has docker images. You can read about installing Dockerhere. Once you have installed docker-engine, you need to start it. Typically it would be
$ sudo service docker start
To avoid having to use sudo when you use the docker command, create a Unix group called docker and add users to it. When the docker daemon starts, it makes the ownership of the Unix socket read/writable by the docker group.
Warning: The docker group is equivalent to the root user; For details on how this impacts security in your system, see Docker Daemon Attack Surface for details.$ sudo groupadd docker $ sudo usermod -aG docker your_username
Log out and login again to ensure your user is running with the correct permissions. You can run the unix id command to confirm that you have the docker group privileges. e.g.
$ id -a uid=1000(mbhangui) gid=1000(mbhangui) groups=1000(mbhangui),10(wheel),545(docker) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023
Now we need to pull the docker image for I…

Writing Filters for IndiMail

IndiMail provides multiple methods by which you can intercept an email in transit and modify the email headers or the email body. A filter is a simple program that expects the raw email on standard input and outputs the message text back on standard output. The program /bin/cat can be used as a filter which simply copies the standard input to standard output without modifying anything. Some methods can be used before the mail gets queued and some methods can be used before the execution of local / remote delivery.

It is not necessary for a filter to modify the email. You can have a filter just to extract the headers or body and use that information for some purpose. IndiMail also provides the following programs - 822addr(1), 822headerfilter(1), 822bodyfilter(1), 822field(1), 822fields(1), 822header(1), 822body(1), 822headerok(1), 822received(1), 822date(1), 822fields(1) to help in processing emails.

Let us say that we have written a script /usr/local/bin/myfilter. The myfilter program …