Hi, please forgive me is this isn't the right place to ask. I've been struggling two days straight to get dynamic shared rosters from Active Directory to work correctly. I msut mention that our DIT is years long and therefore I can't make many big changes, I have to use what is there.

We have two groupings: one for quick overview when managing the tree and for Policy propagation, disposed in coarse OUs. The other one, which is used for the more granular tasks of security mappings in storage, and for mail distribution lists is based on Security and Distribution Groups, of which many are nested. Users and groups that should have mail (and now XMPP) have their mail fields populated with their sAMAccountName@our.domain.com..I have to get the users and groups from the groups, not from the OUs.

My ejabberd authenticates with LDAP to the Active Directory, Vcard information is also pulled from there. These two things are working seamlessly from the start. The non-LDAP shared rosters also worked fine when testing (except for @all@).

The trouble with shared_roster_ldap was that it didn't handle CN's containing spaces, *every* CN here is "FirstName Lastname". Finally solved it by making the module to connect to a local OpenLDAP proxy that maps and rewrites every entry in the member attributes, making another request with the DN and replacing it with the values of sAMAccountNames. In the mapping the attribute itself is renamed to uid. All this is transparent to the module, which sees a member attribute that contains a list of uids with usernames.

Right when the mapping was up, the roster was populated from Active Directory with all users and groups, and the Vcards are correct for every entry.

But the problem is that now I see every user offline, even if they are connected

I don't get it. When I was testing mod_shared_roster, I added sAMAccountName@our.domain.com. and it worked correctly. Now the same is shown in the list but the status isn't updated. When I browse the address with Psi+ It shows it, along with other JIDS that have some kind of ID appended after the domain. I guess this is related to the real problem, but I don't see in what way (or how can I solve it).

I've successfully installed ejabberd from Ubuntu 14.04 repo and configured authentication against Active Directory on Windows Server 2012. My problem is that mod_shared_roster_ldap seems not working properly. It is strange but it doesn't work when mod_shared_roster is down, when I uncommented line with mod_shared_roster users appered on contact list. Every changes that I make in mod_shared_rosted_ldap don't do anything even when I commented mod_shared_roster_ldap with everything that is included in it users (only usernames like for ex. user.name) still appear on roster - is it normal? My goal is to authenticate users against AD and have roster with them, not with usernames but with people names. Any suggestions ?

Currently we try to created shared rosters based on LDAP for the Team and several projects, but have no success to get the ldap_ufilter applied to the members detected by the gfilter.

Did you have any hint for me what's going wrong there?

Here's a example of the LDAP Structure we use + the ldap and mod_shared_roster_ldap module:

LDAP Structure

### OU with all users ##########################################dn: ou=users,dc=lnxcim,dc=example,dc=comobjectClass: organizationalUnitou: usersdescription: OU for all Company Users################################################################

Stock mod_shared_roster_ldap still has a weird requirement that the result of ldap_memberattr be the user part of JID.

If the optional parameter ldap_auth_check is on (default), then each ldap_memberattr result is combined with current ejabberd domain to make full JID, and checked for existence (using auth) before processing any further. That's what is happening in your case.

You may try to set ldap_auth_check to off. But this doesn't guarantee success. Some time ago, the code of ufilter did another weird check that ufilter gave the same thing that ldap_memberattr did. I have not looked into the original source code for quite a long time, so maybe there are some fixes that would allow you to succeed, or maybe not.

(huge list of such messages).
after last of these messages(when _all_ examples of running msrl shuted down), ejabberd is working fine.
when i make start msrl by-hand later, it works fine too to next trouble with timeout.

i did read a lot of documentation and huge pages of google and (in my current opinion) problem is in method of managing and making connection to ldap server.
seems, i began to think, that msrl uses persistent connection and not all of connection, which it takes, are operational. tuning keepalive timeout on server doesn't solve the problem, our firewall has not set to watch for timeout of connections.

my question:
can msrl choice to use poersistent or non-persistent connection?
how can i make it to establish new connecton to ldap?
or what direction i have to take in my searchs to solve this problem?

Seems like a patch needed. I cannot promise anything now, but I'll try to look into it; and if I'll do something I'll leave a note here or at EJAB-1480.

i'd tried again.
now, i think, that it is not ldap problem, it strange rate of connections at all.
when at one moment of time some decades of users try to connect to ejabberd, it takes on approximately 15-18 users quickly and much slowly takes on another users with huge delay between acceptions of connetcions.
why?
i did turn off all max_stanza_size and all shapers in config, but problem persist as in beginning.
what setting in ejabberd server makes connection rate?

Seems like a patch needed. I cannot promise anything now, but I'll try to look into it; and if I'll do something I'll leave a note here or at EJAB-1480.

some interesting(maybe) information:
today i droped ejabberd some times one by once with ~150 connected users.
with msrll or without msrl quick and fine connected was 24 users (may be, 25)
other users had timeoute in endless connections.
i dropped server 5 times (one time i did reject connections to port 5222 before dropping, unload msrl and wait some minutes and then delete fw rules) and quickconnected users was always ~24-25, and after them server goes to timeoutes from ldap.

at last half of test time i did cicle large query (list of all users and attributes) to my ldap server and it answers me always with no delay.

I'm using a text book OpenLDAP setup here and would like to know how I debug the results saved by eldap. My setup is as follows (LDAP auth is all OK and works) with comments added by me to help me understand the various settings as per the docs:

% Here you will search for objects that will % define group list. {ldap_rfilter,"(objectClass=groupOfURLs)"},

% Here we take those objects taken in the % previous step, examine this property, % and build the list of unique strings that % define your groups. {ldap_groupattr,"cn"},

% This will look for users of a single group. % It will be called for each group, with %g % set to the name retrieved from above, e.g. % "GHENRY Staff" from % cn=GHENRY Staff,ou=Groups,dc=ghenry,dc=co,dc=uk. % It will give you the full list of users you % want to see. {ldap_gfilter,"(&(objectclass=groupOfURLs)(cn=%g))"},

% Where we get the roster item name from to % show in the roster {ldap_groupdesc, "description"},

% Define the attribute that holds the "group % member" id. % Note that this will be used to build be the % user part of jid (using % ldap_memberattr_format(_re)) {ldap_memberattr, "member"}, {ldap_memberattr_format,"cn=%u,ou=Users,dc=ghenry,dc=co,dc=uk"},

% Use this to get the single user object {ldap_ufilter,"(&(objectClass=inetOrgPerson)(cn=%u))"},

% This holds the JID as per what we use to % Auth {ldap_useruid, "uid"},

% Use this to set the display name of the % roster item {ldap_userdesc, "cn"}, {ldap_auth_check, "off"}, {ldap_user_cache_validity, "10"}, {ldap_group_cache_validity, "10"} ]}

If you thoughtfully inspect the comments you made yourself to clarify settings, you will see that the answer is there:

Quote:

% Define the attribute that holds the "group
% member" id.
% Note that this will be used to build be the
% user part of jid (using
% ldap_memberattr_format(_re))
{ldap_memberattr, "member"},
{ldap_memberattr_format,"cn=%u,ou=Users,dc=ghenry,dc=co,dc=uk"},

My apologies as I thought the best place to post this was under the module name and didn't check.

I think the docs need cleaned up then. Where can I find the source to create a patch?

Regarding your comment, the key point is the word "build", i.e. build the jid as I understood this process to not be finished at that stage. "ldap_memberattr_format" as per the docs, is used to retrieve %u, which due to there being a ldap_ufilter, what was captured in %u should be used in the filter:

{ldap_ufilter,"(&(objectClass=inetOrgPerson)(cn=%u))"},

which should then be used in a new LDAP search to get the user detail of the user in that group. I've then used useruid to specify to use "uid" as the JID part in JID@domain:

% This holds the JID as per what we use to % Auth {ldap_useruid, "uid"},

Thanks Mike. My directory server isn't live yet so I've changed all user DN from an RDN of cn to uid, e.g. from:

cn=Gavin Henry,ou=Users,dc=ghenry,dc=co,dc=uk

to

uid=ghenry,ou=Users,dc=ghenry,dc=co,dc=uk

and kept cn in the entry to get the display format for the user in the Roster entry.

Also, these LDAP searches can be much more efficient. If you just want uid in member_format and don't want to change the name in the roster from uid to say cn then only one search is needed, e.g. rfilter could get all the rosters, groups and ask for your memberattr.

You oversimplify things.
The simpliest approach would allow for this, but it would disallow for much more flexible patterns.

The rfilter enables to create an URL list holding all roster groups (other URL lists), and then you will need one search to get that list, and it will be unable to bring you the users of those groups.

The ufilter (theoretically, and practically if you use the patch) enables you to handle those cases when the group objects don't hold necessary info to build the jid (your case :)). Unfortunately, the devs didn't do that themselves, that's why that issue exist.

There are many very different ways you can use LDAP, and this module (at least its patched version) is able to cover almost any config.

I understand completely. It's very flexible and is now working. I'll try to look at some config options later.

My shared_roster_ldap settings are all now working thanks to your kind help. Unfortunately, my own JID is appearing in the list. Any ideas why? The LDAP searches look right and it seems to be skipping me as per:

i have three ldap servers with about twelve domains in different offices and one ejabberd server in central office, which does service all offices at ones.
for all offices i made shared rosters with mod_shared_roster_ldap. one roster for one domain. but i still have a few questions:
1. is msrl able to run some different instances with different settings for one domain?
may be with "per host config + global config". i'd have tried this, but without results: msrl run with last settings, that i did.
2. is msrl able to get data from two or more ldap servers or from two or more rootdns ?
one ldap (communigate) has a one ldap tree for each domain, and binding to basedn="" doesn't work. only to basedn="my1.domain.com", etc.

i'm trying find a way to create shared roster for all domains together without making fourth ldap server with whole domain tree and syncing data or integrating communigate servers in external ldap.

1. msrl should be able to run successfully with per-vhost configuration. If it does not, it should be considered a bug. But in this case, you get different shared rosters for different vhosts.
2. It is impossible in current msrl. In theory, it is possible to modify it so that it would become possible to get users from different directories, but in this configuration, it would be impossible to keep the overall phylosophy of this module: to get all needed information from LDAP. It would be possible only to show all users from all servers to each other, while there would be no easy way to restrict one's shared roster groups to some subset of groups from server a + some groups from server b + ... So it seems impractical to modify msrl this way.

1. msrl should be able to run successfully with per-vhost configuration. If it does not, it should be considered a bug. But in this case, you get different shared rosters for different vhosts.
2. It is impossible in current msrl. In theory, it is possible to modify it so that it would become possible to get users from different directories, but in this configuration, it would be impossible to keep the overall phylosophy of this module: to get all needed information from LDAP. It would be possible only to show all users from all servers to each other, while there would be no easy way to restrict one's shared roster groups to some subset of groups from server a + some groups from server b + ... So it seems impractical to modify msrl this way.

we did openldap with slapd-meta+slapd-pcache.
it makes visual all ldap servers as one.

I have been racking my brain for days trying to get this to be configured, so any help would be much appreciated.

I am authing against ldap, and all my users can login, and now I want them to see each other using the ldap shared roster tool. Because the mod_shared_roster @all@ does not support ldap.

Running ejabberd 2.1.8-2 from fedora

My DIT:
base = ou=People,ou=IT,o=school,c=US
Everyone is under this ou
the ldap attribute nsRole needs to be queried for it to be appear (doesnt show up automatically)
the role for everyone that I want to login and show is
nsRole=cn=jabber,ou=IT,o=school,c=US

I have tried various settings but I can not get group to show up. I have got everyone to show in the OU, or in a group, but their CN wont be associated, so all I see are uid's. Its driving me nuts, the polish examples in the documentation are funny and make some sense, so it might just be me, so any help would be appreciated.

{mod_shared_roster_ldap,[
% Disable meaningless default.
{ldap_filter, ""},
% The next line may be redundant if you already have defined ldap_base at the higher level
{ldap_base, "ou=People,ou=IT,o=school,c=US"},
% Here you will search for objects that will define group list.
% In this config you will end up with full list of Persons of your Directory, that's OK.
% All of them will have objectclass equal to "Person".
{ldap_rfilter, "(objectclass=Person)"},
% Here we take those objects taken in the previous step, examine this property,
% and build the list of unique strings that define your groups.
% You will get the list with single entry equal to "Person".
{ldap_groupattr, "objectclass"},
% This will look for users of a single group. In your case,
% it will be called only once, with %g set to "Person".
% It will give you the full list of users you want to see.
{ldap_gfilter, "(&(objectclass=%g)(nsRole=cn=jabber,ou=IT,o=school,c=US))"},
% Define the attribute that holds the "group member" id.
% Note that this will be used to build be the user part of jid (using ldap_memberattr_format(_re))
{ldap_memberattr, "uid"},
% Use this to get the single user object.
{ldap_ufilter, "(uid=%u)"},
{ldap_useruid, "uid"},
% Use this to set the display name of the roster item
{ldap_userdesc, "cn"}
]},

P.S. Next time, don't ask for help from a single specific person. I have read your old post long ago and could try and help if you wouldn't do that.

You are right I posted in the wrong place, this forum is not quite what I am used to.
So I plopped in the filter above, and something is going on. Its querying like crazy. I can see it looking for everyone, but I dont see any mention of the ldap_gfilter being used in the logs. Since the logs dont state it leads me to believe that is why I do not see the group when I log in. Of course I am the only logged on right now, but there is no empty group with all the users.

1. I see that you gave an incomplete data. I thought that you have only one object class per record; this isn't so. I'm afraid that in this case "querying like crasy" will be an understatement :)
I think that both bandwidth and memory will be used like crasy, too. And it will be almost impossible to track down what makes it fail.
By the way, in this case, if everything would work, I would expect to see many groups, not one: they would be "posixAccount", "inetOrgPerson","top", "organizationalPerson", "person", "eduperson" and may be even some others...
2. You didn't post the queries, only results.
3. I think that it's not worth it to debug this problem; maybe you will find it easier to look at the updated module that I wrote about in this thread on july 21st. It may present you more flexibility to reach your goal. There you may find my email in case you would need more assistance.

This is not a russian forum, so please use English or write to the appropriate International forum.

Your problem has nothing to do with "russian OU groups", rather, they are because of the defficiency of the module itself. But you try to use the module without understanding how it works.

Config #0.
You define the ldap_rfilter to select your OUs. Then you try to use the {ldap_groupattr,"department"} to get the "department" LDAP attribute from the OU objects you got to distinguish one group from another. Guess if there is such an attribute in the ad2008's OU? I guess no, and MS seems to agree with me. All the further mistakes in the config have no effect. But I'll try to discuss them, anyway.

Your ldap_gfilter is supposed to select each group (OU in your case) to examine it for its display name (ldap_groupdesc) and its members (ldap_memberattr). You set it to "(&(objectClass=organizationalUnit)(member=%g))", and the %g is substituted with the contents of the ldap_groupattr of each object from the ldap_rfilter search. So your ldap_gfilter is expected to yield the OUs which have "member" attribute set to "department" of another OU??? Note that OUs in MS AD have no "member" attribute at all, and in other objects, this attribute contains DN strings, not some "department" arbitrary strings.

Then, you expect that the group object you select with your ldap_gfilter (i.e. an OU) to list its users in the "displayName" attribute. Hmm... By the way, the contents of ldap_memberattr (and the ldap_memberattr_format(_re)) in the vanilla module is used to construct the user part of the jid.

After that, your ldap_ufilter should select each user object one by one, to get its display name. In the filter "(distinguishedName=%u)", the %u is substituted with the uid (user part of the jid that was constructed at the previous stage), i.e. in your case, you will look for objects that have distinguishedName set to what was in the displayName of an OU. Do you think you will get something?

Config #1.
You define the ldap_rfilter to get all OUs that have their cn ending with underscore. The ldap_groupattr looks sensible enough at the first glance("cn"), but is there any data in cn for OUs in AD? You could examine this yourself with a tool like ldp.exe. I would prefer to use something like objectGUID.
You set ldap_filter to empty string, and don't define the ldap_gfilter, thus it defaults to (&(member=*)(cn=%g)). This will return object that has the cn set to the contents of ldap_groupattr (cn) returned at the previous stage, so if the OUs had cn data, it would be OK.
You look for the members of the group in the "member" attribute. Again, the group object is chosen to be OU, and it haven't any "member" attribute. Then, you try to extract the cn part of the distinguished name you expect to be stored in the member attribute. Note that it will work only with a cn that makes proper user part of jid.
Your ufilter gets that cn and looks for "person" with cn set to this. That's OK.

The overall analysis shows that you didn't read the (by the way, exceptionally precise, thanks to great work of porridge) documentation carefully.

Anyway, the vanilla module is unable to do the job you expect from it - to select users from OUs. You may wish to try the modified version of the module that is available from the page mentioned in the post previous to yours.

I made modifications to the mod_shared_roster_ldap to make it more AD-friendly, and also to make its general use more straightforvard. The modified version is available from the ProcessOne's issue page. The detailed description of changes may be found there,too.

The main feature is that now it's possible to generate user ids ftom another ldap attribute than that is used to find the user in the directory. E.g., it's now possible to specify group users by the "member" attribute of group object in AD, even if user's distinguished name cannot be used to create uid, and then build the uid from sAMAccountName or userPrincipalName.

Other changes include improved caching and less LDAP queries -> less traffic and domain controller load.

Please test it and report any issues you will find to the abovementioned issue page. Also, I need some feedback concerning some further changes. The questions that need your attention are listed there.

Retrieving the roster section of the Installation and Operation Guide:
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 this 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.

I am trying to get ldap shared_roster working for days now...
If I run the ldapsearch on cli I get the correct results, but in the jabberroster I do not see anybode.
Is there more to config besides the mod_shared_roster_ldap?

Do I need to set up a roster and configure a group to see this "ldapgroup"

I need following functionality equal to mod_shared_roster:
1) Edit shared roster with contacts from different jabber servers (different jabber domains)

To this mod I expect I store this roster (group) in LDAP DIT.

2) Get this shared roster by each user (including from different servers) at user login

I expect each jabber server will get shared roster from the LDAP DIT (maybe connecting to different LDAP servers serving the same DIT).

So the questions:
How this mod makes JID (username@servername) for shared roster contacts? I understand that "username" is taken from value of attribute "ldap_useruid" of user entry. What about "servername"?

Can I teach this mod to get JID (username@servername) right from any special attribue (for example, "jabberID" from user entry)? Of course I fixed LDAP schema for adding this attribute to user entry.

PS:
I look for any advices with other ways.
The whole picture: I need deploy some federated servers with "See all online" concept. And I'm looking for an easy way to add new user to this system, i.e. without manual adding this user to rosters at all servers.

Also I'm thinking about Clustering, but there are a lot of questions... Is clustering suitable for system where servers and links between them can be eventually switched off and on.

EDIT: nevermind, I'm just crazy. I already had the users in a different roster, and my IM client didn't put them into the shared LDAP roster for some reason. Once I added a user that wasn't already in my IM client, it showed up under the group just fine. I'll leave this here in case it's useful to anybody.

The commented-out line there is what the page recommends, but that gives me no results, so I changed it to just "%u", and that does give me a shared roster. The problem I'm having is that rather than the roster entries being other@example.com and tsuraan@example.com, I'm getting roster entries of "uid=tsuraan,ou=People,dc=example,dc=com" and "uid=other,ou=People,dc=example,dc=com". This seems like a sort of unique problem, and I don't have any idea why it's happening or how to solve it. If there were some name-manging regex substitute I could apply, then I could hack it that way, but I can't find anything like that. Digging through mod_shared_roster_ldap.erl, I don't even see where the thing builds the foo@bar names; the '@' symbol only appears in the header comment of the file, so I really have no idea how the module is supposed to be building JIDs at all. Any help would be very appreciated.