Affects Version/s: ejabberd 2.0.5, ejabberd 2.1.0, ejabberd 2.1.1, ejabberd 2.1.2, ejabberd 2.1.3, ejabberd 2.1.4, ejabberd 2.1.5, ejabberd 2.1.6, ejabberd 2.1.7, ejabberd 2.1.8
Fix Version/s: ejabberd 16.02
Edit: I decided to write a settings reference for the modified module. It will be updated as needed.
If you need help using the module, please contact me at email@example.com.
The mod_shared_roster_ldap currently isn't flexible enougn to allow easy integration with Active Directory LDAP. The problem is that it expects that the list of users that belong to a group to contain enough information to construct their jids, while it is often not the case.
Retrieving the roster section of the Installation and Operation Guide (http://www.process-one.net/docs/ejabberd/guide_en.html#msrlconfigroster):
Step 2.a performs a query on LDAP to get groups data (this step is executed once).
Step 2.c.i converts the string in ldap_memberattr into the jid.
Step 2.c.ii (optional) checks for existence of this jid (using auth mechanism; thus, it must depend on jid).
Step 3.b.ii.A performs a query on LDAP to get the display name of each jid, at the same time retrieving the ldap_useruid attribute.
Supposedly, the roster is built after the step 3.
This sequence applies some unnecessary restrictions on the LDAP data. Specifically, there are multiple threads on the ejabberd forum with questions concerning the Active Directory integration. In some environments, it's impossible to use this module as intended, and a workaround needs to be implemented to overcome its deficiency.
For example, in AD, the [group object] has an attribute "member" that has entries defining the DNs of its members.
A DN may not contain the necessary information to construct the jid. First, the DN consists of relative distingueshed names, so no part is guaranteed to be unique across the domain, only the DN is. Second, the CN part of DN isn't required to conform to the requirements for the user part of jid. For example, in our environment, I have my DN like "CN=Kaganski Mikhail Borisovich,OU=my_dept,DC=example,DC=com". Note the spaces in the CN.
[user object] contains an attribute, named "sAMAccountName", that is mandatory, is guaranteed to be unique across the domain, and may be used to construct the user part of the jid (at least we could use it in our environment). But I have no means to get this information if I search for group objects first, to get the list of users in those groups.
The module could make use of an alternative path to get the user information. If a new optional parameter would be introduced, e.g. "member_is_DN", with a default walue of "no", and if it is set to "yes", then instead of steps 2.c.i, 2.c.ii and 3.b.ii.A, it would get the object with that DN, and look there for the "ldap_useruid" attribute, then apply the ldap_memberattr_format(_re) to it to get the user part of the jid, and for the "ldap_userdesc" attribute. That could be still done using the "User Filter", and looking for the entry with corresponding DN. This way the AD problem could be solved successfully, while maintaining full compatibility with current version, and having (almost) no impact on performance.