Integration/Active.Directory.iRedMail

From iRedMail

(Difference between revisions)
Jump to: navigation, search
(Verify LDAP query with AD in Dovecot)
(Appendix)
(42 intermediate revisions not shown)
Line 1: Line 1:
__TOC__
__TOC__
-
 
-
TO BE CONTINUED.
 
-
 
-
'''WARNING: NOT FINISHED YET, DO NOT APPLY BELOW STEPS.'''
 
= Summary =
= Summary =
-
'''NOTE''': We just tested this tutorial on Windows 2000 and 2003 server, if you tested it on other versions and works well, please let us know. [http://iredmail.org/contact.html Contact us].
+
'''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. [http://iredmail.org/contact.html Contact us].
Line 15: Line 11:
* Mail list support with group in AD.
* Mail list support with group in AD.
* Global LDAP Address Book with AD in Roundcube Webmail.
* Global LDAP Address Book with AD in Roundcube Webmail.
-
* Account status support. Disable user in Active Directory will cause this account be disabled in iRedMail.
+
* Account status support. Disable user in Active Directory will cause this account disabled in iRedMail.
Line 33: Line 29:
= Install iRedMail =
= Install iRedMail =
-
Please install iRedMail on Linux/BSD with OpenLDAP backend first, we will modify some configure files to achieve AD integration.
+
Please install iRedMail on Linux/BSD with OpenLDAP backend first, we will achieve this AD integration by simply modify some configure files.
Here is [http://iredmail.org/doc.html#installation_guide iRedMail installaion guides].
Here is [http://iredmail.org/doc.html#installation_guide iRedMail installaion guides].
Line 44: Line 40:
** If you want to force LDAP connection with LDAPS, use port 636 instead.
** 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 '@example.com' (Your mail domain is 'example.com').
* Base dn in AD is "dc=example,dc=com", email addresses of all users are ends with '@example.com' (Your mail domain is 'example.com').
-
* All user accounts are placed under dn "cn=Users,dc=example,dc=com". '''Note:''' dn is case-insensitive.
+
* 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.
* 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.
* 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 "support@example.com" will be '''/var/vmail/vmail1/example.com/support/Maildir/''', maildir format.
== Create user account in AD, used for LDAP query ==
== 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 in AD.
+
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.
-
* TODO: Steps to create account '''vmail''' + Screenshots.
+
'''NOTE''':
-
* TODO: How to get dn of vmail. or just use 'vmail' instead of full dn.
+
* [http://www.iredmail.org/forum/post8630.html#p8630 Dovecot will treat characters as comment after a inline '#', so please just don't use '#' in password]
=== Test AD query with ldap command line tool ===
=== Test AD query with ldap command line tool ===
 +
 +
{{cmd|<pre>
 +
# ldapsearch -x -h ad.example.com -D 'vmail' -W -b 'cn=users,dc=example,dc=com'
 +
Enter password: password_of_vmail
 +
</pre>}}
== Enable LDAP query with AD in Postfix ==
== Enable LDAP query with AD in Postfix ==
-
Modify postfix main.cf:
+
Execute below commands to modify Postfix settings to:
-
{{cfg|main.cf|<pre>
+
* Disable unused iRedMail special settings
-
#
+
* Let it query AD instead of OpenLDAP
-
# Add your mail domain in "smtpd_sasl_local_domain" and "virtual_mailbox_domains".
+
-
#
+
-
smtpd_sasl_local_domain = example.com
+
-
virtual_mailbox_domains = example.com
+
-
#
 
-
# Unused iRedMail special settings.
 
-
# Set them to empty value OR comment these lines.
 
-
#
 
-
virtual_mailbox_domains =
 
-
virtual_alias_maps =
 
-
sender_bcc_maps =
 
-
recipient_bcc_maps =
 
-
relay_domains =
+
'''Note''': we will create three AD query files later:
-
relay_recipient_maps =
+
* /etc/postfix/ad_virtual_mailbox_maps.cf
 +
* /etc/postfix/ad_virtual_group_maps.cf
 +
* /etc/postfix/ad_sender_login_maps.cf
 +
 
 +
{{cmd|<pre>
 +
####
 +
# 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='example.com'
 +
# postconf -e virtual_mailbox_domains='example.com'
 +
 
 +
#####
 +
# Change transport maps setting.
 +
#####
 +
# postconf -e transport_maps='hash:/etc/postfix/transport'
 +
#####
 +
# Enable AD query.
#
#
-
# Change some settings.
+
# Note: We will create these 3 files later.
-
#
+
#####
-
# Transport maps.
+
# Used to verify sender.
-
transport_maps = hash:/etc/postfix/transport
+
#####
 +
# postconf -e smtpd_sender_login_maps='proxy:ldap:/etc/postfix/ad_sender_login_maps.cf'
 +
####
# Used to query mail users.
# Used to query mail users.
-
virtual_mailbox_maps = ldap:/etc/postfix/ad_virtual_mailbox_maps.cf
+
####
 +
# postconf -e virtual_mailbox_maps='proxy:ldap:/etc/postfix/ad_virtual_mailbox_maps.cf'
 +
####
# Used to query mail lists/groups.
# Used to query mail lists/groups.
-
virtual_alias_maps = ldap:/etc/postfix/ad_virtual_group_maps.cf
+
####
-
 
+
# postconf -e virtual_alias_maps='proxy:ldap:/etc/postfix/ad_virtual_group_maps.cf'
-
# Used to verify sender.
+
-
smtpd_sender_login_maps = /etc/postfix/ad_sender_login_maps.cf
+
</pre>}}
</pre>}}
Line 106: Line 124:
</pre>}}
</pre>}}
-
* Create/Edit file: '''ad_virtual_mailbox_maps.cf'''
+
* Create/Edit file: '''/etc/postfix/ad_sender_login_maps.cf''':
-
{{cfg|ad_virtual_mailbox_maps.cf|<pre>
+
{{cfg|ad_sender_login_maps.cf|<pre>
server_host    = ad.example.com
server_host    = ad.example.com
server_port    = 389
server_port    = 389
Line 114: Line 132:
start_tls      = no
start_tls      = no
bind_dn        = vmail
bind_dn        = vmail
-
bind_pw        = passwd_of_vmail
+
bind_pw        = password_of_vmail
search_base    = cn=users,dc=example,dc=com
search_base    = cn=users,dc=example,dc=com
scope          = sub
scope          = sub
-
query_filter    = (&(objectclass=person)(userPrincipalName=%s))
+
query_filter    = (&(userPrincipalName=%s)(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
result_attribute= userPrincipalName
result_attribute= userPrincipalName
-
result_format  = %d/%u/Maildir/
 
debuglevel      = 0
debuglevel      = 0
</pre>}}
</pre>}}
-
* Create/Edit file: '''/etc/postfix/ad_sender_login_maps.cf''':
+
* Create/Edit file: '''ad_virtual_mailbox_maps.cf'''
-
{{cfg|ad_sender_login_maps.cf|<pre>
+
{{cfg|ad_virtual_mailbox_maps.cf|<pre>
server_host    = ad.example.com
server_host    = ad.example.com
server_port    = 389
server_port    = 389
Line 131: Line 148:
start_tls      = no
start_tls      = no
bind_dn        = vmail
bind_dn        = vmail
-
bind_pw        = password_of_vmail
+
bind_pw        = passwd_of_vmail
search_base    = cn=users,dc=example,dc=com
search_base    = cn=users,dc=example,dc=com
scope          = sub
scope          = sub
-
query_filter    = (&(userPrincipalName=%s)(objectClass=person)(!(userAccountControl=514)))
+
query_filter    = (&(objectclass=person)(userPrincipalName=%s))
result_attribute= userPrincipalName
result_attribute= userPrincipalName
 +
result_format  = %d/%u/Maildir/
debuglevel      = 0
debuglevel      = 0
</pre>}}
</pre>}}
 +
 +
'''Note:''' Here, we define users' mailboxes to be "example.com/username/Maildir/" in '''"result_format"''' setting.
 +
 +
Maildir of the first example user created during iRedMail installation, www@example.com, is 'example.com/w/w/w/www-[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/ad_virtual_group_maps.cf'''
* Create/Edit file: '''/etc/postfix/ad_virtual_group_maps.cf'''
Line 156: Line 178:
debuglevel      = 0
debuglevel      = 0
</pre>}}
</pre>}}
 +
'''Note''':
 +
* 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/main.cf
 +
* Remove this setting: '''check_policy_service inet:127.0.0.1:7777'''.
== Verify LDAP query with AD in Postfix ==
== Verify LDAP query with AD in Postfix ==
Line 164: Line 193:
{{cmd|<pre>
{{cmd|<pre>
# postmap -q user@example.com ldap:/etc/postfix/ad_virtual_mailbox_maps.cf
# postmap -q user@example.com ldap:/etc/postfix/ad_virtual_mailbox_maps.cf
-
example.com/vmail/Maildir/
+
example.com/user/Maildir/
</pre>}}
</pre>}}
 +
 +
*DEBUG*: If you got blank link instead of output like above example, it means LDAP query doesn't get expected result.
 +
Try to set '''"debuglevel = 1"''' in file '''"ad_sender_login_maps.cf"''', then query again, it now will print more debug message, If you're not familiar with this kind of output message, please [http://www.iredmail.org/forum create a new forum topic] and paste them in your post.
 +
* Verify sender login check:
* Verify sender login check:
Line 173: Line 206:
</pre>}}
</pre>}}
-
* Verify mail list/group:
+
* Verify mail list/group. Steps:
 +
** Create a group in AD, e.g. testgroup@example.com.
 +
** Assign at least one member to this group.
 +
** Execute below command on iRedMail server to verify it can get members.
{{cmd|<pre>
{{cmd|<pre>
-
# postmap -q list@example.com ldap:/etc/postfix/ad_virtual_group_maps.cf
+
# postmap -q testgroup@example.com ldap:/etc/postfix/ad_virtual_group_maps.cf
member01@example.com
member01@example.com
member02@example.com
member02@example.com
</pre>}}
</pre>}}
 +
'''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 ==
== Enable LDAP query with AD in Dovecot ==
-
We need to modify '''/etc/dovecot-ldap.conf''' on RHEL/CentOS or '''/etc/dovecot/dovecot-ldap.conf''' on Debian/Ubuntu, let dovecot queries AD instead of local OpenLDAP server.
+
We need to modify '''/etc/dovecot-ldap.conf''' (RHEL/CentOS) or '''/etc/dovecot/dovecot-ldap.conf''' (Debian/Ubuntu), let dovecot query AD instead of local OpenLDAP server.
{{cfg|dovecot-ldap.conf|<pre>
{{cfg|dovecot-ldap.conf|<pre>
Line 193: Line 230:
scope          = subtree
scope          = subtree
deref          = never
deref          = never
-
user_filter    = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl=514)))
+
user_filter    = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
-
pass_filter    = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl=514)))
+
pass_filter    = (&(userPrincipalName=%u)(objectClass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))
pass_attrs      = userPassword=password
pass_attrs      = userPassword=password
default_pass_scheme = CRYPT
default_pass_scheme = CRYPT
-
user_attrs      = =home=/var/vmail/vmail01/%Ld/%Ln/Maildir/,=mail=maildir:/var/vmail/vmail01/%Ld/%Ln/Maildir/
+
user_attrs      = =home=/var/vmail/vmail1/%Ld/%Ln/Maildir/,=mail=maildir:/var/vmail/vmail1/%Ld/%Ln/Maildir/
</pre>}}
</pre>}}
 +
 +
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:
'''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:
Line 209: Line 248:
}
}
</pre>}}
</pre>}}
-
 
-
* TODO: How to achieve per-user quota in AD.
 
== Verify LDAP query with AD in Dovecot ==
== Verify LDAP query with AD in Dovecot ==
We can use command '''telnet''' to verify AD query in Dovecot.
We can use command '''telnet''' to verify AD query in Dovecot.
 +
 +
'''Note''': Please do restart dovecot before testing.
{{cmd|<pre>
{{cmd|<pre>
-
# telnet localhost 143
+
# telnet localhost 143                         # <- Type this
* OK [...] Dovecot ready.
* OK [...] Dovecot ready.
-
# ---- Type testing command below ----
+
. login user@example.com password_of_user       # <- Type this
-
. login user@example.com password_of_user
+
. OK [...] Logged in
. OK [...] Logged in
 +
                                        # <- Quit telnet with "Ctrl+]", then type 'quit'.
</pre>}}
</pre>}}
Line 243: Line 282:
# Global LDAP Address Book with AD.
# Global LDAP Address Book with AD.
#
#
-
$rcmail_config['ldap_public']["a.cn"] = array(
+
$rcmail_config['ldap_public']["example.com"] = array(
     'name'          => 'Global Address Book',
     'name'          => 'Global Address Book',
     'hosts'        => array("ad.example.com"),    // <- Set AD hostname or IP address here.
     'hosts'        => array("ad.example.com"),    // <- Set AD hostname or IP address here.
Line 270: Line 309:
     'sort'          => 'cn',
     'sort'          => 'cn',
     'scope'        => 'sub',
     'scope'        => 'sub',
-
     //'filter'        => "(&(objectclass=person)(!(userAccountControl=514)))",
+
     //'filter'        => "(&(objectclass=person)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))",
     'filter'        => "(mail=*@*)",
     'filter'        => "(mail=*@*)",
     'fuzzy_search'  => true
     'fuzzy_search'  => true
Line 276: Line 315:
</pre>}}
</pre>}}
-
= Appendix =
+
= Additions =
 +
 
 +
* If your mail domain name is different than Windows Active Directory domain: http://www.iredmail.org/forum/topic3165-integration-with-windows-domain.html
 +
 
 +
= ChangeLog =
 +
* 2011-10-22: Use 'postconf -e' to set Postfix settings instead of edit main.cf 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>.

Revision as of 04:10, 27 March 2012

Contents


Summary

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 bcc control with LDAP. You should use hash file instead.
  • TO BE CONTINUED.

Requirements

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

  • A working Microsoft Windows (2000/2003) server, with Active Directory installed and working, listen on port 389 (ldap://) or 636 (ldaps://).
  • A working Linux/BSD with iRedMail+OpenLDAP installed.
  • iRedMail server can access Windows AD server via port 389 or 636.

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 'ad.example.com', listen on port 389.
    • We will use this hostname below, you can replace it by IP address.
    • 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 '@example.com' (Your mail domain is 'example.com').
  • 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 "support@example.com" will be /var/vmail/vmail1/example.com/support/Maildir/, 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.

NOTE:

Test AD query with ldap command line tool

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

Enable LDAP query with AD in Postfix

Execute below commands to modify Postfix settings to:

  • Disable unused iRedMail special settings
  • Let it query AD instead of OpenLDAP


Note: we will create three AD query files later:

  • /etc/postfix/ad_virtual_mailbox_maps.cf
  • /etc/postfix/ad_virtual_group_maps.cf
  • /etc/postfix/ad_sender_login_maps.cf
Terminal:
####
# 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='example.com'
# postconf -e virtual_mailbox_domains='example.com'

#####
# Change transport maps setting.
#####
# postconf -e transport_maps='hash:/etc/postfix/transport'

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

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

####
# Used to query mail lists/groups.
####
# postconf -e virtual_alias_maps='proxy:ldap:/etc/postfix/ad_virtual_group_maps.cf'
  • Create/Edit file: /etc/postfix/transport:
File: /etc/postfix/transport
example.com dovecot

Run 'postmap' so that postfix can read it:

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

Note: Here, we define users' mailboxes to be "example.com/username/Maildir/" in "result_format" setting.

Maildir of the first example user created during iRedMail installation, www@example.com, is 'example.com/w/w/w/www-[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/ad_virtual_group_maps.cf
File: 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 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/main.cf
  • Remove this setting: check_policy_service inet:127.0.0.1:7777.

Verify LDAP query with AD in Postfix

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

  • Query mail user:
Terminal:
# postmap -q user@example.com ldap:/etc/postfix/ad_virtual_mailbox_maps.cf
example.com/user/Maildir/
  • DEBUG*: If you got blank link instead of output like above example, it means LDAP query doesn't get expected result.

Try to set "debuglevel = 1" in file "ad_sender_login_maps.cf", then query again, it now will print more debug message, If you're not familiar with this kind of output message, please create a new forum topic and paste them in your post.


  • Verify sender login check:
Terminal:
# postmap -q user@example.com ldap:/etc/postfix/ad_sender_login_maps.cf
user@example.com
  • Verify mail list/group. Steps:
    • Create a group in AD, e.g. testgroup@example.com.
    • Assign at least one member to this group.
    • Execute below command on iRedMail server to verify it can get members.
Terminal:
# postmap -q testgroup@example.com ldap:/etc/postfix/ad_virtual_group_maps.cf
member01@example.com
member02@example.com

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-ldap.conf (RHEL/CentOS) or /etc/dovecot/dovecot-ldap.conf (Debian/Ubuntu), let dovecot query AD instead of local OpenLDAP server.

File: dovecot-ldap.conf
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: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 {
    # --- SKIP OTHER SETTINGS HERE ---
    # 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.

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

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

Note: You just type . login user@example.com 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/main.inc.php (RHEL/CentOS) or /usr/share/apache2/roundcubemail/config/main.inc.php (Debian/Ubuntu).

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

File: main.inc.php

#
# "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:1.2.840.113556.1.4.803:=2)))",
    'filter'        => "(mail=*@*)",
    'fuzzy_search'  => true
);

Additions

ChangeLog

  • 2011-10-22: Use 'postconf -e' to set Postfix settings instead of edit main.cf 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