Postfix/Dovecot Authentication Against Active Directory On CentOS 5.x

This document describes how to integrate Postfix/Dovecot with Microsoft Active Directory on CentOS 5.x, and you can manage mail users in Microsoft Active Directory. You will learn how to enable Postfix to look up email addresses in Active Directory and how to enable Dovecot to authenticate against Microsoft Active Directory.

 

1 Requirements

 

2 Preliminary Note

In this tutorial we use two servers.

Linux Mail Server:

  • Linux Mail Server Hostname: mail.example.com
  • IP address: 192.168.1.10
  • LDAP suffix (root dn): dc=example,dc=com
  • The first virtual domain: example.com

Windows Server with Active Directory:

  • Hostname: ad.example.com
  • IP address: 192.168.1.20

 

3 Create User Account In AD For LDAP Query

With iRedMail + OpenLDAP, we have a low-privileged account "cn=vmail,dc=example,dc=com" for queries only. So we create the same account vmail in AD, with a complex password.

Dovecot will treat characters as comments after an inline '#', so please just don't use '#' in the password.

Test AD query with ldap command line tool:

# ldapsearch -x -h ad.example.com -D 'vmail' -W -b 'cn=users,dc=example,dc=com'

  Enter password: password_of_vmail 

 

4 Enable Postfix Query With Active Directory

Modify the Postfix configuration in /etc/postfix/mail.cf, let it query AD instead of OpenLDAP.

Now edit /etc/openldap/server.conf:

#
# Unused iRedMail special settings.
#Set them to empty value OR comment these lines.
#

virtual_alias_maps =
virtual_mailbox_domains =
sender_bcc_maps =
recipient_bcc_maps =

relay_domains =


#
# Add your mail domain in "smtpd_sasl_local_domain" and "virtual_mailbox_domains".
#
smtpd_sasl_local_domain = example.com
virtual_mailbox_domains = example.com

#
# Change some settings.
#
#Transport maps.
transport_maps = hash:/etc/postfix/transport

#remove iRedAPD related settings in Postfix,comment the lines.
check_policy_service inet:127.0.0.1:7777. 

#
# AD query.
#
# Note: We will create these 3 files later.
#
# Used to verify sender.
smtpd_sender_login_maps = proxy:ldap:/etc/postfix/ad_sender_login_maps.cf

# Used to query mail users.
virtual_mailbox_maps = proxy:ldap:/etc/postfix/ad_virtual_mailbox_maps.cf

# Used to query mail lists/groups.
virtual_alias_maps = proxy:ldap:/etc/postfix/ad_virtual_group_maps.cf


Edit /etc/postfix/transport:

example.com dovecot

Run 'postmap' so that postfix can read it:

# postmap hash:/etc/postfix/transport

Create the file /etc/postfix/ad_sender_login_maps.cf:

server_host     = ad.example.com
server_port     = 389
version         = 3
bind            = yes
start_tls       = no
bind_dn         = vmail
bind_pw         = password_of_vmail
search_base     = cn=users,dc=example,dc=com
scope           = sub
query_filter    = (&(userPrincipalName=%s)(objectClass=person)(!(userAccountControl=514)))
result_attribute= userPrincipalName
debuglevel      = 0

Create the file ad_virtual_mailbox_maps.cf:

server_host     = ad.example.com
server_port     = 389
version         = 3
bind            = yes
start_tls       = no
bind_dn         = vmail
bind_pw         = passwd_of_vmail
search_base     = cn=users,dc=example,dc=com
scope           = sub
query_filter    = (&(objectclass=person)(userPrincipalName=%s))
result_attribute= userPrincipalName
result_format   = %d/%u/Maildir/
debuglevel      = 0

Create the file /etc/postfix/ad_virtual_group_maps.cf:

server_host     = ad.example.com
server_port     = 389
version         = 3
bind            = yes
start_tls       = no
bind_dn         = vmail
bind_pw         = password_of_vmail
search_base     = cn=users,dc=example,dc=com
scope           = sub
query_filter    = (&(objectClass=group)(mail=%s))
special_result_attribute = member
leaf_result_attribute = mail
result_attribute= userPrincipalName
debuglevel      = 0

Note: If your users have email addresses in both "mail" and "userPrincipalName", you will get duplicate results. Commenting 'leaf_result_attribute' can fix it.

 

5 Verify LDAP Query With AD In Postfix

Query mail user:

# postmap -q [email protected] ldap:/etc/postfix/ad_virtual_mailbox_maps.cf

  example.com/user/Maildir/ 

Verify sender login check:

# postmap -q [email protected] ldap:/etc/postfix/ad_sender_login_maps.cf

  [email protected] 

Active Directory has a type of grouping called Distribution group used solely as an email distribution list.Verify steps:

  • Create a group in AD, e.g. [email protected].
  • Assign at least one member to this group.
  • Execute below command on iRedMail server to verify it can get members.

# postmap -q [email protected] ldap:/etc/postfix/ad_virtual_group_maps.cf

[email protected]
[email protected]

 

6 Enable LDAP Query With AD In Dovecot

Modify /etc/dovecot-ldap.conf:

Let dovecot query AD instead of the local OpenLDAP server. After modifying, you need to restart the dovecot service to make it work immediately.

hosts           = ad.example.com:389
ldap_version    = 3
auth_bind       = yes
dn              = vmail
dnpass          = passwd_of_vmail
base            = cn=users,dc=example,dc=com
scope           = subtree
deref           = never
user_filter     = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl=514)))
pass_filter     = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl=514)))
pass_attrs      = userPassword=password
default_pass_scheme = CRYPT
user_attrs      = =home=/var/vmail/vmail1/%Ld/%Ln/Maildir/,=mail=maildir:/var/vmail/vmail1/%Ld/%Ln/Maildir/

Verify LDAP querying with AD in Dovecot:

  # telnet localhost 143

* OK [...] Dovecot ready.

. login [email protected] password_of_user # <- Type this
. OK [...] Logged in
# <- Quit telnet with "Ctrl+]", then type 'quit'.

 

7 Enable Global LDAP Address Book WiTh AD In Roundcube WebMail

Edit the roundcube config file /var/www/roundcubemail/config/main.inc.php. You can remove the existing LDAP address book which is stored in OpenLDAP, and add a new one with AD.

#
# "sql" is personal address book stored in roundcube database.
# "example.com" is new LDAP address book with AD, we will create it below.
#
$rcmail_config['autocomplete_addressbooks'] = array("sql", "example.com");

#
# Global LDAP Address Book with AD.
#
$rcmail_config['ldap_public']["example.com"] = array(
    'name'          => 'Global Address Book',
    'hosts'         => array("ad.example.com"),     // <- Set AD hostname or IP address here.
    'port'          => 389,
    'use_tls'       => false,                 // <- Set to true if you want to use LDAPS. Change port to 636 on above line too.

    // ---- Used to search accounts only in the same domain. ----
    'user_specific' => false,
    'base_dn'       => "cn=users,dc=example,dc=com",   // <- Set base dn in AD
    'bind_dn'       => "vmail",                     # <- bind dn
    'bind_pass'     => "password_of_vmail",                    // <- bind password
    'writable'      => false,                       # <- Do not allow mail user write data back to AD.
    'ldap_version'  => "3",

    // ---- Search ----
    //'search_fields' => array('displayname', 'userprincipalname', 'sn', 'givenname',),  // <- fields to search in
    'search_fields' => array('mail', 'cn', 'sAMAccountName', 'displayname', 'sn', 'givenName'),
    //'name_field'    => 'displayname',
    'name_field'    => 'cn',
    //'email_field'   => 'userprincipalname',
    'email_field'   => 'mail',
    'surname_field' => 'sn',
    //'firstname_field' => 'givenname',
    'firstname_field' => 'givenName',
    //'sort'          => 'displayname',
    'sort'          => 'cn',
    'scope'         => 'sub',
    //'filter'        => "(&(objectclass=person)(!(userAccountControl=514)))",
    'filter'        => "(mail=*@*)",
    'fuzzy_search'  => true
);

 

Share this page:

6 Comment(s)