From iRedMail
Revision as of 19:56, 2 October 2013 by ZhangHuangbin (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search



NOTE: We just tested this tutorial on Windows 2000, 2003, 2008 R2 server, if you tested it on other versions and works well, please let us know. Contact us.

With AD + iRedMail integration, you can get below features:

  • User authentication against Windows Active Directory. You can now manage mail domains, users, mail lists with AD.
  • Mail list support with group in AD.
  • Global LDAP Address Book with AD in Roundcube Webmail.
  • Account status support. Disable user in Active Directory will cause this account disabled in iRedMail.

Since AD uses different LDAP schema, you will lose some iRedMail special features. e.g.

  • Per-user, per-domain service control with LDAP (e.g. enable/disable POP3/IMAP/SMTP services). You should use hash file instead.


To integrate Microsoft Active Directory with iRedMail, you should have:

  • A working Linux/BSD server with iRedMail+OpenLDAP installed.
  • A working Microsoft Windows (2000/2003) server, with Active Directory installed and working properly, listen on port 389 (ldap://) or 636 (ldaps://), and allow LDAP connections from iRedMail server.

Install iRedMail

Please install iRedMail on Linux/BSD with OpenLDAP backend first, we will achieve this AD integration by simply modify some configure files.

Here is iRedMail installaion guides.

Integrate Microsoft Active Directory

We assume:

  • Hostname of your AD server is '', listen on port 389.
    • We will use this hostname below, you can replace it by IP address of this AD server if you want.
    • If you want to force LDAP connection with LDAPS, use port 636 instead.
  • Base dn in AD is "dc=example,dc=com", email addresses of all users are ends with '' (Your mail domain is '').
  • All user accounts and mail list accounts are placed under dn "cn=Users,dc=example,dc=com". Note: dn is case-insensitive.
  • For ldap connection, protocol version '3' is recommended. All pupular LDAP servers support LDAP protocol version 3.
  • Store all mails on Linux/BSD servers, not on AD server.
    • Storage directory is /var/vmail/vmail1, same as default in iRedMail.
    • Mailbox of user "" will be /var/vmail/vmail1/, maildir format.

Create user account in AD, used for LDAP query

With iRedMail + OpenLDAP, we have a low-privileged account "cn=vmail,dc=xxx,dc=xxx" for query only. So we suggest you create a same account vmail in AD, with complex password.


Test AD query with ldap command line tool on iRedMail server

We should make sure this newly created user is able to connect to AD server, so please verify it with below command on iRedMail server:

# ldapsearch -x -h -D 'vmail' -W -b 'cn=users,dc=example,dc=com'
Enter password: password_of_vmail

If it prints all users stored in AD server, then it's working as expected.

Enable LDAP query with AD in Postfix

We will execute some commands to modify Postfix settings to:

  • Disable unused iRedMail special settings.
  • Authenticate against AD server instead of local OpenLDAP server.

Note: we will create three AD query files later:

  • /etc/postfix/
  • /etc/postfix/
  • /etc/postfix/

  • Disable unused iRedMail special settings:
# postconf -e virtual_alias_maps=''
# postconf -e sender_bcc_maps=''
# postconf -e recipient_bcc_maps=''
# postconf -e relay_domains=''
# postconf -e relay_recipient_maps=''
  • Add your mail domain in "smtpd_sasl_local_domain" and "virtual_mailbox_domains":
# postconf -e smtpd_sasl_local_domain=''
# postconf -e virtual_mailbox_domains=''
  • Change transport maps setting:
# postconf -e transport_maps='hash:/etc/postfix/transport'
  • Enable AD query. Note: We will create these 3 files later.
    • Verify SMTP senders
# postconf -e smtpd_sender_login_maps='proxy:ldap:/etc/postfix/'
    • Used to verify local mail users
# postconf -e virtual_mailbox_maps='proxy:ldap:/etc/postfix/'
    • Used to verify local mail lists/groups.
# postconf -e virtual_alias_maps='proxy:ldap:/etc/postfix/'
  • Create/Edit file: /etc/postfix/transport.
File: /etc/postfix/transport dovecot

Note: dovecot here is a Postfix transport defined in /etc/postfix/, used to deliver received emails to user mailboxes.

Run 'postmap' so that postfix can read it:

# postmap hash:/etc/postfix/transport
  • Create/Edit file: /etc/postfix/
File: /etc/postfix/
server_host     =
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:1.2.840.113556.1.4.803:=2)))
result_attribute= userPrincipalName
debuglevel      = 0
  • Create/Edit file: /etc/postfix/
File: /etc/postfix/
server_host     =
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

Note: Here, we define users' mailboxes to be "" in "result_format" setting.

Maildir of the first example user created during iRedMail installation,, is '[TIMESTAMP]/Maildir/', and this maildir path is stored in OpenLDAP (attribute "mailMessageStore"). But we don't store maildir path in Active Directory, so we hard-code maildir path here.

  • Create/Edit file: /etc/postfix/
File: /etc/postfix/
server_host     =
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


  • If your user have email address in both "mail" and "userPrincipalName", you will get duplicate result. Comment 'leaf_result_attribute' can fix it.
  • If your group account doesn't contains attribute 'mail' and 'userPrincipalName', please try 'query_filter = (&(objectClass=group)(sAMAccountName=%u))' instead.

Also, we need to remove iRedAPD related settings in Postfix:

  • Open /etc/postfix/
  • Remove this setting: check_policy_service inet:

Verify LDAP query with AD in Postfix

We can use command line tool postmap to verify AD query in postfix.

  • Query mail user:
# postmap -q ldap:/etc/postfix/
  • DEBUG: If nothing returned by the command, it means LDAP query doesn't get expected result. Please set "debuglevel = 1" in file "", then query again, it now will print more debug message, If you're not familiar with this kind of output message, please post the debug message in our forum to ask help.
  • Verify sender login check:
# postmap -q ldap:/etc/postfix/
  • Verify mail list/group. Steps:
    • Create a group in AD, e.g.
    • Assign at least one member to this group.
    • Execute below command on iRedMail server to verify it can get members.
# postmap -q ldap:/etc/postfix/

postmap will return nothing if 1) mail group doesn't exist; 2) group doesn't have any members.

Enable LDAP query with AD in Dovecot

We need to modify /etc/dovecot/dovecot-ldap.conf, let dovecot query AD instead of local OpenLDAP server.

File: dovecot-ldap.conf
hosts           =
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:1.2.840.113556.1.4.803:=2)))
pass_filter     = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
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/

Now restart dovecot service to make it work immediately.

Note: we don't have per-user quota limit here, you can set a hard-coded quota for all users in /etc/dovecot.conf (RHEL/CentOS) or /etc/dovecot/dovecot.conf (Debian/Ubuntu). Example:

File: dovecot.conf
plugin {
    # Format: integer + M/G/T.
    # M -> MB, G -> GB, T -> TB.
    quota_rule = *:storage=1G

Verify LDAP query with AD in Dovecot

We can use command telnet to verify AD query in Dovecot.

Note: Please do restart dovecot before testing.

# telnet localhost 143                         # <- Type this
* OK [...] Dovecot ready.

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

Note: You just type . login password (Do NOT miss the dot) in above testing, if it returns Logged in, then dovecot + AD works as expected.

Enable Global LDAP Address Book wih AD in Roundcube webmail

Edit roundcube config file: /var/www/roundcubemail/config/ (RHEL/CentOS) or /usr/share/apache2/roundcubemail/config/ (Debian/Ubuntu).

You can remove exist LDAP address book which stored in OpenLDAP, and add a new one with AD.


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

# Global LDAP Address Book with AD.
$rcmail_config['ldap_public'][""] = array(
    'name'          => 'Global Address Book',
    'hosts'         => array(""),      // <- 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:1.2.840.113556.1.4.803:=2)))",
    'filter'        => "(mail=*@*)",
    'fuzzy_search'  => true



  • 2011-10-22: Use 'postconf -e' to set Postfix settings instead of edit directly.
  • 2011-07-15: Replace 'userAccountControl=514' with 'userAccountControl:1.2.840.113556.1.4.803:=2'. This will still work if the user has additional attributes like password expired or never changes. Thanks Rick Culler <rculler@caresouth>.
Personal tools