This module is included in ejabberd since the release of ejabberd 2.1.6.
Name: mod_shared_roster_ldap Purpose: LDAP shared roster management Author: Marcin Owsiany (porridge), Evgeniy Khramtsov and Realloc Type: Module Requirements: Download: ejabberd-msrl. Older version: mod_shared_roster_ldap.erl
Check also the mod_shared_roster_ldap documentation



more than one ldap server or rootdn in shared roster
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.
Re: more than one ldap server or rootdn in shared roster
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.
configuring nsRoles with ldap shared Roster
Hello,
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
example:
base = ou=People,ou=IT,o=school,c=US =below this => uid=GIR,ou=People,ou=IT,o=school,c=US
GIR has these other normal attributes
uid = gir
cn = Gir Loves Bacon
sn = BACON
objectclass=Person
nsRole=cn=jabber,ou=IT,o=school,c=US
The ldap searches work fine, and they look like this, it will show the uid of everyon that has this attribute.
ldapsearch -x -b "ou=people,ou=IT,o=school,c=us" "(nsRole=cn=jabber,ou=people,ou=it,o=school,c=us)" uid
==
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.
Thank you,
GIR
Try this
{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
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.
Thanks Mike,
Gary
Here is what I do see for all queries of the people in the logs:
looking for person / first search:
D(<0.455.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "uid=fong,ou=people,ou=it,o=school,c=us", [{'PartialAttributeList_SEQOF', "objectclass", ["posixAccount", "inetOrgPerson","top", "organizationalPerson","person", "eduperson"]}]}}what i guess is the search for the cn? :
=INFO REPORT==== 2011-10-25 09:39:45 === D(<0.282.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "uid=fong,ou=people,ou=it,o=school,c=us", [{'PartialAttributeList_SEQOF',"uid", ["fong"]}]}} =INFO REPORT==== 2011-10-25 09:39:45 === D(<0.282.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "uid=abraham,ou=people,ou=it,o=school,c=us", [{'PartialAttributeList_SEQOF',"uid", ["abraham"]}]}}1. I see that you gave an
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.
shared_roster_ldap and ad2008
Попытался получить ростер с AD2008, но увы не получается.
схема такая:
DC=dmain,DC=local -> OU=Организация -> OU=Отдел -> CN=ФИОcn= ФИО
department= Название Отдела
displayName= ФИО
distinguishedName= CN=ФИО,OU=Отдел,OU=Организация,DC=dmain,DC=local
name= ФИО
objectClass= person
objectClass= organizationalPerson
objectClass= user
sAMAccountName= userlogin
пробовал как написано было раньше другими:
{mod_roster, [{versioning, true}, {store_current_id, false}]},{mod_shared_roster,[]},
{mod_shared_roster_ldap,[
{ldap_base, "dc=dmain,dc=local"},
{ldap_rfilter,"(objectClass=organizationalUnit)"},
{ldap_gfilter,"(&(objectClass=organizationalUnit)(member=%g))"},
{ldap_ufilter,"(distinguishedName=%u)"},
%% {ldap_filter, "(&(&(objectClass=user)(objectClass=person)(objectClass=organizationalPerson))(!(&(OU=_*)(OU=Cisco)(OU=Domain*)(objectClass=computer)(CN=Users))))"},
{ldap_filter, ""},
{ldap_groupattr,"department"},
{ldap_groupdesc,"name"},
{ldap_memberattr,"displayName"},
{ldap_userdesc,"userPrincipalName"},
{ldap_useruid,"sAMAccountName"}
]},
{mod_shared_roster_ldap,[{ldap_base, "dc=dmain,dc=local"},
{ldap_groupattr, "cn"},
{ldap_memberattr, "member"},
{ldap_filter, ""},
{ldap_memberattr_format_re, "CN=(\[^,\]*),(OU=.*,)*DC=dmain,DC=local"},
{ldap_ufilter, "(&(objectClass=person)(CN=%u))"},
{ldap_rfilter, "(&(objectClass=organizationalUnit)(CN=*_))"},
{ldap_user_cache_validity, 1},
{ldap_auth_check,off},
{ldap_useruid, "cn"},
{ldap_userdesc, "sAMAccountName"}
]},
но в итоге не получаю ничего. ни групп ни пользователей в ростере(кроме тех кого добавил сам руками по поиску).
по поиску vcard их находит и выводит информацию нормально. на сервере тоже по ldap авторизуется.
версия 2.1.8. модуль брал и из поставки с джаббером и с сайта разработчика.
в логах не ругается.
Грешу на то, что OU группы русские.
Re: shared_roster_ldap and ad2008
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.
Whoa
Your reply above makes more sense than the documentation. Thanks!
New version of mod_shared_roster_ldap is ready for testing
Hello everyone using LDAP shared rosters!
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.
AD integration improvement suggestion
Hello porridge!
Thank you for your work supporting this module.
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.
Thank you for your consideration.
generally question
Hi there,
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"
thx for any help in advance
greets
Unit test
I'm trying to use unit tests from this mod source.
Test is crashed at "mock:new".
There is the only mention in doc about "added unit tests for several important functions, using a couple of mocking libraries".
There is in source next message:
%%% The tests require gen_server_mock and mock modules. They are not otherwise
%%% required for using the module with ejabberd.
I found gen_server_mock at https://github.com/jashmenn/gen_server_mock Is that correct module?
What about the other "mock modules"?
.
I'm trying to use unit tests from this mod source.
Test is crashed at "mock:new".
There is the only mention in doc about "added unit tests for several important functions, using a couple of mocking libraries".
There is in source next message:
%%% The tests require gen_server_mock and mock modules. They are not otherwise
%%% required for using the module with ejabberd.
I found gen_server_mock at https://github.com/jashmenn/gen_server_mock Is that correct module?
What about the other "mock modules"?
That should have read:
The tests require the "gen_server_mock" and "mock" modules.
Looks like you found the first one. The second one is http://sheyll.blogspot.com/2009/02/erlang-mock-erlymock.html
.
The second one is http://sheyll.blogspot.com/2009/02/erlang-mock-erlymock.html
I found this link earlier, but there isn't any link to download this module. It looks like the project involved and become uncompatible with mod_shared_roster_ldap's unit tests.
I get the version of this link before editing (http://web.archive.org/web/20090503161036/http://sheyll.blogspot.com/200...). This link doesn't contain any link to mock module.
Do you know any link for this mock modules?! Or maybe do you have original version of modules? Can you upload it somewhere or send it by email?
The file is there inline on
The file is there inline on the page. But to download try for example:
http://anonscm.debian.org/gitweb/?p=ejabberd-msrl/ejabberd-msrl.git;a=bl...
JID forming
I have some questions about using this mod.
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.
why is this subject required?
I have some questions about using this mod.
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.
Or rather ldap_memberattr, treated with ldap_memberattr_format(_re).
What about "servername"?
It's the same as the servername of the user whose roster is being displayed,
i.e. the servername of the configured ejabberd virtual server.
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.
Not without code changes.
Bad field. Why not automated with "Re:"?
What about "servername"?
It's the same as the servername of the user whose roster is being displayed,
i.e. the servername of the configured ejabberd virtual server.
So, this is a serious functional limitation that differs this mod from standart mod_shared_roster.
I didn't get it from mod documentation. I suggest to fix this in doc.
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.
Not without code changes.
So, I start to look into code. But I think it will be not easy for such erlang beginnner like me. Any helpful advices are welcome. :)
.
What about "servername"?
It's the same as the servername of the user whose roster is being displayed,
i.e. the servername of the configured ejabberd virtual server.
So, this is a serious functional limitation that differs this mod from standart mod_shared_roster.
I didn't get it from mod documentation. I suggest to fix this in doc.
I agree this should be documented and/or fixed.
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.
Not without code changes.
So, I start to look into code. But I think it will be not easy for such erlang beginnner like me. Any helpful advices are welcome. :)
I recommend "Programming Erlang" by Joe Armstrong. :-)
work with openldap (zimbra opensource edition)
whis config mod_shared_roster_ldap(0.5.3) working with openldap(zimbra OSE 7.0.1):
{mod_roster,[]},
{mod_shared_roster,[]},
{mod_shared_roster_ldap,[
{ldap_base, "dc=example,dc=com"},
{ldap_rfilter, "(objectClass=*)"},
{ldap_filter,""},
{ldap_ufilter,"(uid=%u)"},
{ldap_groupattr,"cn"},
{ldap_groupdesc,"description"},
{ldap_memberattr,"memberUid"},
{ldap_memberattr_format,"%u"},
{ldap_useruid, "uid"},
{ldap_userdesc,"displayName"}
]},
Weird problem with roster entries
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.
Since I'm just setting up LDAP as I'm setting up ejabberd, I copied the deep group structure that is presented on the http://ejabberd-msrl.alioth.debian.org/doc/0.5.3/msrl.html#htoc1 documentation page. So, the ldif for a user looks like:
dn: uid=tsuraan,ou=People,dc=example,dc=comuid: tsuraan
cn: tsuraan
objectClass: account
objectClass: posixAccount
objectClass: top
userPassword: {crypt}x
loginShell: /bin/bash
uidNumber: 1000
gidNumber: 1000
homeDirectory: /home/tsuraan
And the ldif for a group looks like this:
dn: cn=Programmers,ou=jabber-groups,dc=example,dc=comcn: Programmers
description: All the programmers
objectClass: groupOfUniqueNames
uniqueMember: uid=tsuraan,ou=People,dc=example,dc=com
uniqueMember: uid=other,ou=People,dc=example,dc=com
In my config for mod_shared_roster_ldap, I have:
{mod_shared_roster_ldap,[{ldap_base, "dc=example,dc=com"},
{ldap_rfilter, "(objectClass=groupOfUniqueNames)"},
{ldap_filter, ""},
{ldap_gfilter, "(&(objectClass=groupOfUniqueNames)(cn=%g))"},
{ldap_groupdesc, "description"},
{ldap_groupattr, "cn"},
{ldap_memberattr, "uniqueMember"},
%{ldap_memberattr_format, "uid=%u,ou=People,dc=example,dc=com"},
{ldap_memberattr_format, "%u"},
{ldap_ufilter, "(&(objectClass=posixAccount)(cn=%u))"},
{ldap_userdesc, "uid"},
{ldap_useruid, "uid"},
{ldap_auth_check, "on"}
]}
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.
You managed to solve the
You managed to solve the problem of mapping users in the roster??? I have is problem, but not search solve. if you succeed, tell me please mailto: assker at list dot ru
SOLVED!!! see above
Пользователь в разных группах одновременно.
Я настроил сортировку пользователей по группам, пришлось добавить в атрибут каждого пользователя новый параметр postalAddress
==================================================
{ldap_rfilter, "(objectClass=inetOrgPerson)"},
{ldap_groupattr, "postalAddress"},
{ldap_memberattr, "uid"},
{ldap_filter, "(objectClass=inetOrgPerson)"},
{ldap_userdesc, "displayName"}
==================================================
Вопрос к вам такой, можно ли сделать чтобы один пользователь был членом 2х групп одновременно? Я предположил что можно параметр ldap_groupattr использовать с двумя значениями "postalAddress" и "postOfficeBox" эти оба атрибута прописаны у пользователя.
Как правильно записать в конфиге?
может как-то так: {ldap_groupattr, "(&(postalAddress)(postOfficeBox))"},
или так: {ldap_memberattr, [{"postalAddress"},{"postOfficeBox"}]},
В общем у меня не заработало с такими параметрами.
Помогите пожалуйста кто знает......
Попробуйте описать фильтр
Попробуйте описать фильтр следующим образом:
(&(postalAddress)|(postOfficeBox))"},
Подробнее тут
Use with AD
I am unable to get mod_shared_roster_ldap working properly with Active Directory.
I am able to get it to query my user objects for sAMAccountName to find the user objects but each user is in his/her own roster group.
Can the module put all users in a single static roster group or somehow look to the OU for roster group name?
You'd need an attribute whose
You'd need an attribute whose value is the same across all your users.
ldap_userdesc - multiple attributes?
I would like the roster to be displayed as:
FirstName LastName
Where Firstname=givenName and LastName=sn in an LDAP directory.
I don't see any way that I can specify multiple attributes to ldap_userdesc. Any suggestions?
Static AD Group Roster
I have found many issues with configuring dynamic AD groups for population of shared rosters. Seems that the features required to resolve CN's to SamAccountnames is not working or cannot be filtered within the module. However I have yet to find just a simple single static group setup for AD that would just query a single group, or even just pull all the users from an OU, and populate a shared roster. Does anyone have any examples or a similar idea?
conf doesnt work for my ldap case
Hello everyone,
I am really confused to get mod_share_roster_ldap to work on my server. I am running Version 2.1.6 of ejabberd and wrote my mod conf as quoted below:
{mod_shared_roster_ldap,[{ldap_base, "dc=mydomain,dc=com"},
{ldap_rfilter, "(objectClass=posixGroup)"},
{ldap_filter, ""},
{ldap_gfilter, "(&(objectClass=posixGroup)(cn=%g))"},
{ldap_groupdesc, "description"},
{ldap_memberattr, "memberUid"},
{ldap_memberattr_format, "memberUid=%u"},
{ldap_ufilter, "(&(objectClass=inetOrgPerson)(uid=%u))"},
{ldap_userdesc, "displayName"}
]},
My Directory looks like this:
dc=mydomain,dc=com
>ou=groups
>>ou=orga
>>>cn=office1
description=User of office1
objectClass=posixgroup
memberUid=user1
memberUid=user2
>>>cn=office2
description=User of office2
objectClass=posixgroup
memberUid=user3
>ou=people
>>uid=user1
displayName=John Smith
objectClass=inetOrgPerson
>>uid=user2
displayName=Peter Smith
objectClass=inetOrgPerson
>>uid=user3
displayName=Michael Smith
objectClass=inetOrgPerson
Can anyone help me with the right configuration. My brain is overheating at this moment. :)
I'd prefer to get all Users in office1 in one shared roster. office2 is not supposed to have a shared roster.
Thanks.
try removing format
Try removing the following:
{ldap_memberattr_format, "memberUid=%u"},or set it to "%u"
Hey, thanks for the response.
Hey,
thanks for the response. Didn't see it till now. I tried it out. Didn't work for me.
Guess I have to spend a lot more time with LDAP. :)
Registered Users List from LDAP in database, not in clients
Hello everyone,
I've been beating my head against the keyboard for a couple of days on this, and I think it is time to ask for help. I am running ejabberd 2.1.6 with ldap auth and mod_shared_roster_ldap. I am using a Windows 2008 AD backend. ldap auth is working and I can login via the client and chat, get presence, etc.
The issue is the roster. I see no groups or users. I have set the log level to 5 and can see the ldap queries grabbing a list of ldap groups, and then enumerating users out of these groups. When I run the command ejabberdctl registered-users "domain.com" I get a list of all of my users. I'm stumped as to why this isn't working!
Here are some relevant sections of my config:
{auth_method, ldap}. {ldap_servers, ["kxdc01", "kxdc02"]}. {ldap_port, 3268}. {ldap_uids, [{"sAMAccountName"}]}. {ldap_filter, "(memberOf=*)"}. {ldap_base, "dc=domain,dc=com"}. {ldap_rootdn, "svn.authenticator@domain.com"}. {ldap_password, "************"}. {host_config, "domain.com", [{auth_method, ldap}]}. ......... {mod_shared_roster_ldap, [ {ldap_servers, ["kxdc01"]}, {ldap_port, 3268}, {ldap_encrypt, none}, {ldap_rootdn, "svn.authenticator@domain.com"}, {ldap_password, "*************"}, {ldap_base, "CN=Users,DC=domain,DC=com"}, {ldap_auth_check, off}, {ldap_user_cache_validity, 10}, {ldap_group_cache_validity, 10}, {ldap_rfilter, "(&(objectClass=group)(|(cn=Finance)(cn=Systems)(cn=Executives) (cn=Account Services)(cn=Coaching)(cn=Creative)(cn=Business Development)))"}, {ldap_groupattr, "cn"}, {ldap_filter, ""}, {ldap_gfilter, "(&(objectClass=group)(CN=%g))"}, {ldap_groupdesc, "name"}, {ldap_memberattr, "member"}, {ldap_memberattr_format, "CN=%u,CN=Users,DC=domain,DC=com"}, {ldap_ufilter, "(&(objectClass=user)(CN=%u))"}, {ldap_useruid, "sAMAccountName"}, {ldap_userdesc, "displayName"} ]},Some output from the log file:
=INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:675) : {searchRequest, {'SearchRequest',"CN=Users,DC=domain,DC=com", wholeSubtree,neverDerefAliases,0,5,false, {'and', [{equalityMatch, {'AttributeValueAssertion',"objectClass", "group"}}, {'or', [{equalityMatch, {'AttributeValueAssertion',"cn","Finance"}}, {equalityMatch, {'AttributeValueAssertion',"cn","Systems"}}, {equalityMatch, {'AttributeValueAssertion',"cn","Executives"}}, {equalityMatch, {'AttributeValueAssertion',"cn", "Account Services"}}, {equalityMatch, {'AttributeValueAssertion',"cn","Coaching"}}, {equalityMatch, {'AttributeValueAssertion',"cn","Creative"}}, {equalityMatch, {'AttributeValueAssertion',"cn", "Business Development"}}]}]}, ["cn"]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "CN=Finance,CN=Users,DC=domain,DC=com", [{'PartialAttributeList_SEQOF',"cn", ["Finance"]}]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "CN=Systems,CN=Users,DC=domain,DC=com", [{'PartialAttributeList_SEQOF',"cn", ["Systems"]}]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "CN=Executives,CN=Users,DC=domain,DC=com", [{'PartialAttributeList_SEQOF',"cn", ["Executives"]}]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "CN=Account Services,CN=Users,DC=domain,DC=com", [{'PartialAttributeList_SEQOF',"cn", ["Account Services"]}]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "CN=Coaching,CN=Users,DC=domain,DC=com", [{'PartialAttributeList_SEQOF',"cn", ["Coaching"]}]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "CN=Creative,CN=Users,DC=domain,DC=com", [{'PartialAttributeList_SEQOF',"cn", ["Creative"]}]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "CN=Business Development,CN=Users,DC=domain,DC=com", [{'PartialAttributeList_SEQOF',"cn", ["Business Development"]}]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResDone, {'LDAPResult',success,[],[],asn1_NOVALUE}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:675) : {searchRequest, {'SearchRequest',"CN=Users,DC=domain,DC=com", wholeSubtree,neverDerefAliases,0,5,false, {'and', [{equalityMatch, {'AttributeValueAssertion',"objectClass", "group"}}, {equalityMatch, {'AttributeValueAssertion',"CN", "Account Services"}}]}, ["cn","name","member"]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResEntry, {'SearchResultEntry', "CN=Account Services,CN=Users,DC=domain,DC=com", [{'PartialAttributeList_SEQOF',"cn", ["Account Services"]}, {'PartialAttributeList_SEQOF',"member", ["CN=Tori Wadzita,CN=Users,DC=domain,DC=com", "CN=Melissa Rasmussen,CN=Users,DC=domain,DC=com", "CN=Erin Keegan,CN=Users,DC=domain,DC=com", "CN=Cynthia Marias,CN=Users,DC=domain,DC=com", "CN=Claire Reinert,CN=Users,DC=domain,DC=com"]}, {'PartialAttributeList_SEQOF',"name", ["Account Services"]}]}} =INFO REPORT==== 2010-12-30 22:44:00 === D(<0.365.0>:eldap:746) : {searchResDone, {'LDAPResult',success,[],[],asn1_NOVALUE}}etc etc etc etc etc
Output from ejabberdctl:
Any help would be great. Thanks!!
Jack
user IDs are not valid nodenames
Hi Jack,
Thanks for the clear and complete debugging information.
Hello everyone,
I've been beating my head against the keyboard for a couple of days on this, and I think it is time to ask for help. I am running ejabberd 2.1.6 with ldap auth and mod_shared_roster_ldap. I am using a Windows 2008 AD backend. ldap auth is working and I can login via the client and chat, get presence, etc.
The issue is the roster. I see no groups or users. I have set the log level to 5 and can see the ldap queries grabbing a list of ldap groups, and then enumerating users out of these groups. When I run the command ejabberdctl registered-users "domain.com" I get a list of all of my users. I'm stumped as to why this isn't working!
Here are some relevant sections of my config:
{ldap_memberattr, "member"}, {ldap_memberattr_format, "CN=%u,CN=Users,DC=domain,DC=com"},Some output from the log file:
{'PartialAttributeList_SEQOF',"member", ["CN=Tori Wadzita,CN=Users,DC=domain,DC=com",The issue is that the code assumes that the part of memberattr which "%u" matches is a valid nodename (i.e. something you can put ahead of "@" in a Jabber ID). In this case it's "Tori Wadzita" which is not a valid nodename, so it just silently ignores the user.
This is actually a known feature request, as non-nodename user IDs seem to be popular in Active Directory:
https://alioth.debian.org/tracker/index.php?func=detail&aid=312703&group...
There is a patch there, but I haven't taken a close look at it yet.
There is currently no ETA on when I'm going to implement such functionality. So unless someone else does it, or you manage to reference your users by a nodename, you're out of luck.
still not resolved or usable workaround???
Hi,
for me it looks like I have the same problem:
Using ejabberd 2.1.9 on OpenLDAP
My cn shows "firstname surname" (in fact "givenname sn").
I have a special attribute ecaIM in OpenLDAP which holds the NodeID "firstname.surname".
The groupmembership is represented by member: uid=Uxxxx,ou=users,... I think this is my problem! But how can I solve it?
I´m able to login using this NodeID with different clients (Miranda, PSI).
However I was not able to show up any roster information, weather groups nor users.
This is one of my configs (I tried a lot of other versions)
{ldap_memberattr, "member"},
%%only use groups as roster beginning with ka
{ldap_rfilter, "(&(objectClass=groupOfNames)(cn=ka*))"},
{ldap_filter, ""},
{ldap_gfilter, "(&(objectClass=groupOfNames)(cn=%g))"},
%% {ldap_groupdesc, "description"},
%% ecaPerson = inetorgPerson and additional attributes eg ecaIM
{ldap_ufilter, "(&(objectClass=ecaPerson)(ecaIM=%u))"},
{ldap_useruid, "imECA"},
{ldap_userdesc, "cn"}
*SOS* - any help would be more than appreciated!
regards
Jos
Consider this:
https://support.process-one.net/browse/EJAB-1480
AD and mod_shared_roster_ldap
There is currently no ETA on when I'm going to implement such functionality. So unless someone else does it, or you manage to reference your users by a nodename, you're out of luck.
Well there's not much of a chance for me to get AD to bend to my will, and that's probably going to break a bunch of other stuff if I start messing with it. I was looking at get_user_part_re, and it seems to me that if it would allow a substitution (s/ / /) you could pretty much do whatever you wanted. I don't know erlang so I have a learning curve to climb. Let me know if there's any way to us to prioritize your stack (cash, beer, snacks, etc), this is a feature that many enterprises would love to have.
Thanks,
jack
I'm assuming that
I'm assuming that substitution would make it work for you because you have a simple mapping of user's CN to nodename by stripping whitespace?
Note that it's not going to save the day for every AD user. Or am I misunderstanding?
As for prioritization, it's just that recent OS upgrade has destroyed my testbed VM and merging of the module by ejabberd folks requires me to first have a look at how things changed and possibly revive the unit tests. Together this makes any ejabberd-msrl hacking a relatively big chunk of work compared to my other pet projects.
A proposition to consider
Hello porridge,
Thank you for your hard work on this module.
Hope you have managed to restore your development environment.
As to the topic,
I wanted to recall my post to this page dated Tue, 2010-01-12 12:13. Unfortunately, I didn't track the changes to the code for some time, and I cannot be sure that my proposition still makes sense, but maybe it's worth consideration.
In the AD, the user object has no fields specifying groups that the user belongs to. Instead, group object holds the multi-value property which items are full qualified LDAP name of the member (it may be a user or another group). Of course, this information doesn't nesessarily contain the user part of the jid.
After the mod_shared_roster_ldap finds the users that belong to a group, it looks for their display names. (The caching mechanism doesn't change things - the logic remains). The object that contains the display name MUST contain the user part of the jid (or jid itself) - the current implementation already searches for the jid. Let it look for both display name AND jid in one query - and if the jid field is the same as the search key field, then the result will be the same as it is now, and if the fields are different, we will have extra flexibility.
I want to apologize if my post is based on incorrect assumptions.
Keep up the great work.
eJabberd, mod_shared_roster_ldap and Active Directory
Hi all,
I just implemented an extension to query the "sAMAccountName" from LDAP in case there is a space in the CN.
I am sure there is a better way to do it (as I already have set user_uid to "sAMAccountName" - but somehow this module only works with the cn). I had to change the function group_entries_to_dict/7 to group_entries_to_dict/8 to include the complete Status record - in mod_shared_roster_ldap_helpers.erl and the call to this function in mod_shared_roster_ldap.erl...
group_entries_to_dict(State, GroupIDAttr, GroupDescAttr, GroupMemberAttr, Host, ExtractProcessor, AuthProcessor, Entries) ->lists:foldl(
fun(#eldap_entry{attributes=Attrs}, Dict) ->
case {eldap_utils:get_ldap_attr(GroupIDAttr, Attrs),
eldap_utils:get_ldap_attr(GroupDescAttr, Attrs),
lists:keysearch(GroupMemberAttr, 1, Attrs)}
of
{ID, Desc, {value, {GroupMemberAttr, Members}}} when ID =/= "" ->
JIDs = lists:foldl(
fun({ok, UID}, L) ->
FirstSpace = string:str(UID, " "),
Filter = [eldap_filter:do_sub(State#state.ufilter, [{"%u", UID}])],
if
FirstSpace > 0 ->
Ret = eldap_search(State,Filter, [State#state.user_uid]),
if
Ret /= [] ->
{eldap_entry, _, Attribs} = lists:last(Ret),
[NewUID] = proplists:get_value(State#state.user_uid, Attribs);
true ->
NewUID = UID
end;
true ->
NewUID = UID
end,
%%io:fwrite("NewUID ~s~n", [NewUID]),
PUID = jlib:nodeprep(NewUID),
case PUID of
error -> L;
_ ->
case AuthProcessor(PUID, Host) of
true -> [{PUID, Host} | L];
_ -> L
end
end;
(_, L) ->
L
end,
[],
lists:map(ExtractProcessor, Members)
),
NewInfo = #group_info{desc = Desc, members = lists:usort(JIDs)},
dict:update(ID,
fun(OldInfo) ->
OldMembers = OldInfo#group_info.members,
NewMembers = NewInfo#group_info.members,
OldInfo#group_info{members = lists:umerge(OldMembers, NewMembers)}
end,
NewInfo, Dict);
_ ->
Dict
end
end,
dict:new(),
Entries
).
Inefficient, I know - especially since userid value is already loaded before, but somehow not transmitted to this function. But it works for me. Here for everyone with the same problem.
It took me a while to get into the functional programming again.
Cheers, beasti.
EDIT: To test this you also need to change line 589-592 of mod_shared_roster_ldap to
RetrievedDict = mod_shared_roster_ldap_helpers:group_entries_to_dict(State,
State#state.group_attr, State#state.group_desc, State#state.uid,
State#state.host, Extractor, Checker, Retrieved
),
and have the options for this module as following:
{ldap_memberattr_format_re, "CN=([,=]*),(OU=.*,)*DC=xxxxx,DC=yyy"},Note: This last regexp is used to capture the cn of this active directory user.
Group membership based on gidNumber?
Hi,
I've been looking for an example config where the jabber roster group membership is based on only the gidNumber attribute of the posixAccount schema.
E.g. In the following entry, the jabber group would be 10251 (Systems), but that group does not have a corresponding memberUid for user jbloggs (as gidNumber already does this). We use gidNumber as the users primary group and would like them to show up in that group in the jabber roster. We use memberUid only for secondary groups, and do not want the user to appear in this group in the jabber roster.
Is this confuration supported by this module? I can't seem to find any examples of how it would be configured if it is?
dn: uid=jbloggs,ou=people,dc=domain,dc=org
shadowMin: 1
cn: Joe Bloggs
objectClass: ldapPublicKey
objectClass: shadowAccount
objectClass: posixAccount
objectClass: inetOrgPerson
objectClass: eduPerson
shadowMax: 365
uid: jbloggs
title: Developer
mail: jbloggs@domain.org
loginShell: /bin/bash
displayName: Joe Bloggs
shadowWarning: 10
shadowInactive: 10
o: DOM
gecos: Joe Bloggs
sn: Bloggs
homeDirectory: /home/jbloggs
givenName: Joe
uidNumber: 10161
gidNumber: 10251
dn: cn=systems,ou=group,dc=domain,dc=org
sambaGroupType: 2
displayName: Systems
cn: systems
objectClass: posixGroup
gidNumber: 10251
description: Systems
Try the flat schema example?
I think the flat DIT (http://ejabberd-msrl.alioth.debian.org/doc/0.5.3/msrl.html#htoc17) should work for you.
"ou" in that example maps to "gidNumber" in yours. However I don't think the code would be able to use your "human-readable" group name ("Systems") in that case, so your group name would be numeric, which is probably less than ideal.
New mod_shared_roster_ldap version: 0.5.3
The changes are:
No longer work properly attribute "ldap_userdesc" in v 0.5.2
I used the module mod_shared_roster_ldap v 0.3.0 with ejabberd-2.1.3 on freebsd 7.3-RELEASEp2 with openldap-server-2.4.23. Design was used as the first example of documentation (3.4.1 Flat DIT):
ejabberd.cfg
...
{mod_shared_roster_ldap,[
{ldap_base, "ou=mailusers,dc=domain,o=org"},
{ldap_rfilter, "(mail=*)"},
{ldap_groupattr, "ou"},
{ldap_memberattr, "uid"},
{ldap_userdesc, "cn"},
{ldap_port, 389},
{ldap_servers, ["ldap.server.address"]},
{ldap_password, "xxxxxxxxx"},
{ldap_rootdn, "cn=xxxxxxxx,dc=domain,o=org"}
]},
...
ldif:
...
dn: uid=eugene, ou=MailUsers, dc=domain, o=org
...
objectClass: inetOrgPerson
userPassword: 1234567890
ou: Our Depatment
uid: eugene
mail: eugene@domain.ru
cn: Eugene V. Boontseff
...
In the roster contact was visible in the match, with (ldap_userdesc, "cn") as "Eugene V. Boontseff"
After I updated version of ejabberd to 2.1.4, a version mod_shared_roster_ldap to 0.5.2,
contact in the roster was seen as: "eugene". Ie attribute "uid" instead of "cn", regardless of what is set to "ldap_userdesc".
And ldap log records are no longer visible form:
slapd[1157]: SRCH "ou=mailusers,dc=domain,o=org" 2 0
slapd[1157]: 0 0 0
mail slapd[1157]: filter: (&(&(uid=username)(ou=*))(objectClass=inetOrgPerson))
mail slapd[1157]: attrs:
mail slapd[1157]: cn
After a rollback to previous versions all working again normally.
I beg your forgiveness.
I do not carefully read the "release notes". I had to determine "ldap_userid == ldap_memberattr.
As they say: if all else fails, read the last documentation.
repeated LDAP errors and msrl crash
ejabberd 2.1.4 w/ mod_shared_roster_ldap 0.5.2. LDAP auth and vcard work just fine, but when I enable mod_shared_roster_ldap I get the errors below. I have double checked all LDAP settings (similar to Deep DIT example).
Any help would be greatly appreciated.
=INFO REPORT==== 2010-09-01 00:55:43 ===I(<0.371.0>:eldap:967) : LDAP connection on ad5.private:636
=ERROR REPORT==== 2010-09-01 00:55:43 ===
W(<0.371.0>:eldap:589) : LDAP server closed the connection: ad5.private:636
In State: wait_bind_response
=INFO REPORT==== 2010-09-01 00:55:43 ===
I(<0.371.0>:eldap:967) : LDAP connection on ad5.private:636
=ERROR REPORT==== 2010-09-01 00:55:43 ===
W(<0.371.0>:eldap:589) : LDAP server closed the connection: ad5.private:636
In State: wait_bind_response
=ERROR REPORT==== 2010-09-01 00:55:44 ===
'mod_shared_roster_ldap_private' crashed: {timeout,
{gen_server,call,
['mod_shared_roster_ldap_private',
{get_user_displayed_groups,
"as375097"},
10000]}}
Timeouts are usually a sign
Timeouts are usually a sign that the queries needed to process a single call to the module take too long when added up.
Try disabling ldap_auth_check.
Disabling ldap_auth_check
Disabling ldap_auth_check made no difference.
It seems connection is dropped by the LDAP server
Looking at the message:
LDAP server closed the connection: ad5.private:636
In State: wait_bind_response
it seems that the LDAP server is dropping the connection while the module is awaiting bind response. Perhaps you've exceeded some resource limit on the server side?
Unfortunately I don't have any more ideas other than "go look at the LDAP server logs".
New mod_shared_roster_ldap version: 0.5.2
This release makes the module compatible with ejabberd 2.1.4 (bug #312628)