mod_shared_roster_ldap - LDAP Shared Roster Management

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: integrated into the proper ejabberd distribution

For historical information only (outdated): ejabberd-msrl project, documentation for old releases, an early mod_shared_roster_ldap.erl file.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

DN in member attribute in AD <> sAMAccountName

I have successfully used mod_shared_roster_ldap v0.3.0 to integrate ejabberd to an OpenLDAP server with no problems what so ever.

Recently I tried to integrate to an Active Directory server in our organization, but without success.
I believe my problem is described here, http://www.igniterealtime.org/builds/openfire/docs/latest/documentation/...
See "ldap.posixMode"
The groups has the members in a member attribute which uses the distinguishedName and that doesn't match the sAMAccountName that's used to login
E.g "CN=Homer Simpson,OU=Springfield,OU=People,DC=simpsons,DC=com" vs hsi (hsi@simpsons.com as jid)

Here is some examples from our AD.
I have stripped the unnecessary details and changed domainname, usernames, groupnames etc.
CN=Office A,OU=Groups,DC=simpsons,DC=com

2 groups:
objectClass top
objectClass group
cn Office A
distinguishedName CN=Office A,OU=Groups,DC=simpsons,DC=com
member CN=Homer Simpson,OU=Springfield,OU=People,DC=simpsons,DC=com
member CN=Marge Simpson,OU=Springfield,OU=People,DC=simpsons,DC=com
name Office A
sAMAccountName Office A

objectClass top
objectClass group
cn Office B
distinguishedName CN=Office B,OU=Groups,DC=simpsons,DC=com
member CN=Bart Simpson,OU=Springfield,OU=People,DC=simpsons,DC=com
name Office B
sAMAccountName Office B

3 users:
cn Homer Simpson
objectClass top
objectClass person
objectClass organizationalPerson
objectClass user
distinguishedName CN=Homer Simpson,OU=Springfield,OU=People,DC=simpsons,DC=com
sAMAccountName hsi

cn Marge Simpson
objectClass top
objectClass person
objectClass organizationalPerson
objectClass user
distinguishedName CN=Marge Simpson,OU=Springfield,OU=People,DC=simpsons,DC=com
sAMAccountName msi

cn Bart Simpson
objectClass top
objectClass person
objectClass organizationalPerson
objectClass user
distinguishedName CN=Bart Simpson,OU=Springfield,OU=People,DC=simpsons,DC=com
sAMAccountName bsi

I'm trying to achieve this:
Office A
- hsi@simpsons.com
- msi@simpsons.com

Office B
- bsi@simpsons.com

Group membership is only specified on the group, member attribute, not on the user.
So no memberOf or equivalent
I'm unable to do any changes to the AD

Any ideas?

How to have human-friendly roster item names?

Hi,

It seems that get_user_name() in mod_shared_roster_ldap is meant to provide a way to return the roster items with a name different than the UserID retrieved using GroupFilter in get_group_users(). For example so that you can have "John Smith" appear in your roster, rather than "jsmith".

I cannot find a way to make it work, though. It seems to be due to the problem described here:
https://alioth.debian.org/tracker/index.php?func=detail&aid=312171&group...
I'm using a DIT which is similar to the one shown at https://alioth.debian.org/docman/view.php/100433/4084/msrl.html#htoc12

I have a preliminary patch that introduces more configuration parameters, which allow one to specify the User and/or Group filters manually, rather than have them constructed automatically. But maybe I'm simply missing something and it's possible to make it work without changing the code? Did anyone get it to work? What is your configuration and DIT layout?

regards,
Marcin

Working human-friendly names

I did. My config is here.
FreeBSD 7.2 + ejabberd 2.0.5 + AD (Win2003).
By the way, the "bug" you refer in the link above is not exactly a bug. The idea is to make it possible to use in the shared rosters not only the LDAP objects, but also LDAP multi-value properties. So that it's possible to use an object as group, and its multi-valued property as the users list.

Probably it would be desirable to use the rfilter to find the group descriptions, thus separating group handling and user handling, and minimizing the likeliness of breaking some working config.

Different ways to specify group membership.

Quote:

I did. My config is here.

Thanks!

Quote:

By the way, the "bug" you refer in the link above is not exactly a bug. The idea is to make it possible to use in the shared rosters not only the LDAP objects, but also LDAP multi-value properties. So that it's possible to use an object as group, and its multi-valued property as the users list.

It's interesting you say that, because that's exactly the DIT layout that I'm trying to use: groups are objectClass:posixGroup (with members' IDs stored in memberUid multivalued attributes), while users are separate objects of objectClass:inetOrgPerson.

From looking at your config, I can see that it's not the layout you are using. You seem to only have user objects, and your rfilter retrieves group names by listing all "memberOf" attributes of all your users, and taking unique values. Is that correct?
By the way, what objectClass does "memberOf" belong to? Is it some AD-specific thing? I cannot find it in the schemas provided with OpenLDAP.

Those seem to be different paradigms: whether to define group membership on the user-object side, or the group-object side.

It seems that in the paradigm I'm using (group objects, members defined by their memberUids) it's not possible to have get_user_name() work properly.

Quote:

Probably it would be desirable to use the rfilter to find the group descriptions, thus separating group handling and user handling, and minimizing the likeliness of breaking some working config.

I'm not sure what you're suggesting here? AFAICT specifying an rfilter is the only way to use the module, and that's what I'm doing.

I see. This page in Russian

I see. This page in Russian discuss the same thing.
As I see, the problem is that this module is written in such a presumption that all the needed info is kept in one object (you can query some object for group name, user id, and user name at the same time). You may either use users objects where some of their property designate their group, and some other is their full name, or a group object with a name property and a multi-value users property, though here is no way to specify their display name.
I'm afraid that this is by design. It's because it builds queries from the simple property names given in the parameters. You cannot make a simple solution by restructuring the queries, as it will be inflexible in some other way. If you start adding new properties, you will end up with a pile of similar options that are very difficult to understand for user. Maybe the sensible solution is let user specify the queries themself, not options for them, clearly specifying the purpose and the expected return of each, assuming that as the user is trying to work with LDAP (s)he knows something about its structure and query? And as there is quite a big number of users of one specific scheme (I mean AD), it will be simple to provide a reference working query for this case.
The "memberOf" is a simple string that I fill manually :).

New mod_shared_roster_ldap version: 0.3.0

I've created a new version which adds a couple of options that let you work around the aforementioned problem. It's available at:
https://alioth.debian.org/projects/ejabberd-msrl/

This version is backwards-compatible in the sense that it works just like the previous one in case you do not specify any of the new options.

I've also updated the documentation and added an alternative configuration example, for "flat" tree layouts.

Regarding the last comment

Regarding the last comment (DN in member attribute in AD <> sAMAccountName):

For now, the logic is that we look into "group" (whatever it is) to find the jabber users (so, to find those jids!!!). After that, we make another query to look for their display name.
Maybe it's good to change this logic to something like that: we look into "group" to find "user keys", assuming nothing about their syntax, and after that, for each "user key", we perform another query with user-defined filter to find all the jabber-related information, including both jid and display name. IMO, that could be made with no overhead and in a way that is backwards-compatible. This would lead to the change in the get_user_roster.

Re: New mod_shared_roster_ldap version: 0.3.0

Great job!

I've read the dox you've prepared. Clear and simple.
Maybe it's worth it to add the explanation how the new options are handled into the section 3.2? Because if you just read this chapter to understand how it's started up, you will not get the idea of these new options.
And it would be great to know the kind of the result these filters must provide (single/multiple records). It's clear from the examples, but I feel it desirable to be specified it in the corresponding section where the parameters are defined.

Thank you.

Edit: Sorry, I've missed the mention of the new parameters in the 3.2. So please ignore the first question.

New mod_shared_roster_ldap project page

Hello,

I have created a project for this module on Alioth:
https://alioth.debian.org/projects/ejabberd-msrl/

The goal is to improve the state of this code by providing a central place for:
- documentation
- version control
- bug tracker

I hope that when I can bring it to a state where the code and documentation may be considered for inclusion into the mainstream ejabberd code base. However so far I think that a simple forum page without proper version control is not enough for proper maintenance.

So far on the project page you can find release 0.1.1. The module source code is a bit outdated compared to what is currently available for download from this page. However the major deliverable for this release is the documentation (in HTML and PDF formats) which explains how to use the module, together with example DIT tree diagram and example configuration.

My next goal is to merge in the recent changes from this page.

--
Marcin

Version 0.2.0 released

Note, I've just released version 0.2.0, which brings it in sync with the version available from this page.

regexp compilation warning

Hi!

I use FreeBSD and everything is installed from the ports. My compiler complains with this warning which does not allow me to get a .beam output

/mod_shared_roster_ldap.erl:544: Warning: regexp:sub/3: the regexp module is deprecated (will be removed in R15A); use the re module instead

Unfortunately, I have no idea how to convert the line from regexp to re. The complete line is

case regexp:sub(Pattern, "%u", Result) of
{ok,String,_} ->
{ok,Result};
_ ->
{error,badmatch}
end

Or is there a newer version of this file that doesn't use the regexp anymore?
Thanks!

As you said, this is a

As you said, this is a warning, only a warning, of a future problem. The beam file should be generated. Compilation of ejabberd 2.1.0 with Erlang/OTP R13B shows many of those warnings, and it works perfectly.

Suggest improvements

  1. It would be nice to reduce the amount of issued LDAP queries. I suggest change the edit_user_roster function:
    get_user_roster(Items, US) ->
      {U, S} = US,
      DisplayedGroups = get_user_displayed_groups(US),
      %% Get shared roster users in all groups and remove self:
      SRUsers =
        lists:foldl(
          fun(Group, Acc1) ->
            %% =======> Add the next line:
            GN = get_group_name(S, Group),
            lists:foldl(
              fun(User, Acc2) ->
                if User == US -> Acc2;
                   true -> dict:append(User,
                                       %% =======> Change the next line:
                                       %% get_group_name(S, Group),
                                       %% =======> to this:
                                       GN,
                                       Acc2)
                end
              end, Acc1, get_group_users(S, Group))
          end, dict:new(), DisplayedGroups),
    ...

    This will query for the group name once for each group, not for every user of the group.

  2. The results of LDAP queries are not nodeprep'd. It leads to some bugs, one of them is that if a user has uppercase cyrillic letters in his user part of jid, then he cannot see the presence state of other users in his shared roster when he logs in. The (partial) solution is to modify function handle_call({get_group_users, Group}, _From, State):
    ...
      case catch get_user_part(User, UAF) of
         {ok, U} ->
             %% ======> Change the next 2 lines:
             %%case ejabberd_auth:is_user_exists(U, Host) of
             %%   true -> [{U, Host} | Acc];
             %% ======> to these 3 lines:
             LU = jlib:nodeprep(U),
             case ejabberd_auth:is_user_exists(LU, Host) of
                true -> [{LU, Host} | Acc];
                _ -> Acc
             end;
         _ -> Acc
      end
    ...

    As I see in the source code of the ejabberd, there's no general rules of handling the jids: some functions repeatedly STRINGPREP strings, others that may face non-normalized strings forget to do this. It would be nice to determine the points where the jids enter the server code, and make sure that in every such point the normalization takes place, and do not do it elsewhere, as it would be unnecessary (this would become the invariant). This would probably improve the overall performance, and surely would reduce the bugs count.

applied both fixes

Thanks. I've applied both fixes to the published file.

By the way, the first fix

By the way, the first fix could be applied to mod_shared_roster, too...

Right, there was the same

Right, there was the same problem in ejabberd svn. Thanks, it's fixed now.

mod_shared_roster_ldap not works!, my logs>

Hi all, привет всем!
i have probleme:
i download sources from svn.process-one.net/ejabberd 7 make file, so all it works, but i can't configure mod_shared_roster_ldap , its not work, i think it is because mod not load or maybe other...
my logs, when i start server:

root@gateway:/etc/ejabberd# ejabberdctl restart
root@gateway:/etc/ejabberd# sudo tail -f /var/log/ejabberd/ejabberd.log
                               {gen_server,call,
                                   [mod_shared_roster_ldap_jabber,stop]}}

=ERROR REPORT==== 2009-07-09 14:13:44 ===
E(<0.5530.0>:gen_mod:95) : {noproc,
                               {gen_server,call,
                                   [mod_shared_roster_ldap_gateway,stop]}}

=INFO REPORT==== 2009-07-09 14:13:44 ===
I(<0.5530.0>:ejabberd_app:83) : ejabberd 2.1.0-alpha is stopped in the node ejabberd@localhost

p.s. OS: Ubuntu 9.04 server

Patch for mod_shared_roster.erl (eJabberD 2.0.3)

I have looked around and put all the pieces together. This has been tested and works as expected using the Full Name as the Roster item name for the jid. No additional modules are needed for LDAP VCard information to populate Shared Rosters..

badlop.. you may want to upload this patch to the bug system in reference to major differences between 1.x and 2.x mod_shared_roster
https://support.process-one.net/browse/EJAB-114

--- mod_shared_roster.erl.orig  2009-02-11 11:46:49.000000000 -0500
+++ mod_shared_roster.erl       2009-02-12 10:12:17.000000000 -0500
@@ -154,13 +154,29 @@
     SRItems = [#roster{usj = {U, S, {U1, S1, ""}},
                       us = US,
                       jid = {U1, S1, ""},
-                      name = "",
+                      name = get_rosteritem_name(U1, S1),
                       subscription = both,
                       ask = none,
                       groups = GroupNames} ||
                  {{U1, S1}, GroupNames} <- dict:to_list(SRUsersRest)],
     SRItems ++ NewItems1.

+get_rosteritem_name(U, S) ->
+       From = jlib:make_jid("", S, mod_shared_roster),
+       To = jlib:make_jid(U, S, ""),
+       IQ = {iq,"",get,"vcard-temp","",
+   {xmlelement,"vCard",[{"xmlns","vcard-temp"}],[]}},
+       IQ_Vcard = mod_vcard_ldap:process_sm_iq(From, To, IQ),
+               case IQ_Vcard#iq.sub_el of
+               [] -> "";
+               [Vcard] ->
+       case xml:get_path_s(Vcard, [{elem, "FN"}, cdata]) of
+       "" -> xml:get_path_s(Vcard, [{elem, "NICKNAME"}, cdata]);
+  Nickname -> Nickname
+       end
+end.
+
+
%% This function rewrites the roster entries when moving or renaming
%% them in the user contact list.
process_item(RosterItem, Host) ->

Enjoy!

I don't understand what you explain.

I don't understand what you explain.

yohnson wrote:

badlop.. you may want to upload this patch to the bug system in reference to major differences between 1.x and 2.x mod_shared_roster
https://support.process-one.net/browse/EJAB-114

The patch that you show here is almost the same than was previously posted in https://support.process-one.net/browse/EJAB-114
The only difference is that this once calls mod_vcard_ldap:process_sm_iq to get the stored Vcard.

yohnson wrote:

I have looked around and put all the pieces together. This has been tested and works as expected using the Full Name as the Roster item name for the jid. No additional modules are needed for LDAP VCard information to populate Shared Rosters..

Do you mean mod_shared_roster_ldap is not required at all, for anything, in ejabberd 2.0.3?

The file doesn't seem to be

The file doesn't seem to be available anymore, nor was there any comment on how to implement it. Is this still being developed? The perl script put's all users into one group so that's only "OK" for small environments.

Reuploaded, check local link

muldini wrote:

The file doesn't seem to be available anymore, nor was there any comment on how to implement it.

I found the file in Google cache and have uploaded to this site. Check the download link now.

I think it isn't actively developed, or documented. It seems that the module is enabled in ejabberd.cfg, 'modules' section, as usual:

{modules, [
  {mod_shared_roster_ldap, [
                            {ldap_base, ""},
                            {ldap_groupattr, "cn"},
                            {ldap_filter, "(uniqueMember=*)}
  ]},
  ...
]}.

Check the comments for more examples.

updateGroups.pl

Due to problems with mod_shared_roster_ldap I ended up writing a simple perl script to copy our whole directory of users into the mnesia database for mod_shared_roster. Perhaps it will be of use to others. Its very simple (one huge contact list) but it seems to work fine, though I would think twice about this approach with a really large directory.

Compatibility

  • The script assumes that LDAP_ATTRIB contains the full jid (user@host.whatever)
  • Net::LDAP is required (under Debian: apt-get install libnet-ldap-perl).
  • This relies upon ejabberdctl commands which I suspect are extensions. Regardless they appear to be included with Debian's ejabberd package
#!/usr/bin/perl -w

use strict;
use Net::LDAP;

#####START OF CONFIGURABLE OPTIONS#####
use constant LDAP_SERVER => "ldap.example.co.uk";
use constant LDAP_BIND => "";
use constant LDAP_PASSWD => "";

use constant USER_BASE => "ou=users,dc=example,dc=co,dc=uk";
use constant USER_FILTER => "(accountStatus=active)";
use constant LDAP_ATTRIB => "mail";

use constant GROUP_NAME => "example";
use constant GROUP_DESC => "Example Shared Roster";
use constant SERVER_NAME => "example.co.uk";

use constant DEBUG_LDAP => 0;
use constant QUERY_TIMEOUT => 30;
#####END OF CONFIGURABLE OPTIONS#####

warn("LDAP: Connecting to ".LDAP_SERVER) if(DEBUG_LDAP);
my $ldap=Net::LDAP->new(LDAP_SERVER, onerror => undef, async => 0 );

if(!$ldap)
{
        warn "LDAP: Error connecting to ".LDAP_SERVER.": $@";
        return;
}

my $result;
warn("LDAP: Binding as ".LDAP_BIND) if(DEBUG_LDAP);
if(LDAP_BIND eq "")
{
        $result=$ldap->bind;
}
elsif(LDAP_PASSWD eq "")
{
        $result=$ldap->bind(LDAP_BIND);
}
else
{
        $result=$ldap->bind(LDAP_BIND, password => LDAP_PASSWD);
}

if($result->code())
{
        warn("LDAP: Error binding: [user: ".LDAP_BIND."]: ".$result->error()) if(DEBUG_LDAP);
        return;
}
warn("LDAP: Success binding") if(DEBUG_LDAP);

system("ejabberdctl", "srg-delete", GROUP_NAME, SERVER_NAME);
system("ejabberdctl", "srg-create", GROUP_NAME, SERVER_NAME, GROUP_NAME, GROUP_DESC, GROUP_NAME);

#Used to ensure cleanup of server connection
LDAP_BLOCK:
{
        my $result=$ldap->search
          (
                base => USER_BASE,
                filter=> USER_FILTER,
                time=> QUERY_TIMEOUT);
        if($result->code())
        {
                warn "Search error: ".$result->error()
                  if(DEBUG_LDAP);
                last LDAP_BLOCK;
        }
        my $count=$result->count();
        warn "LDAP: User count: ".$count
          if(DEBUG_LDAP);
        NAME_LOOP: for(my $i=0; $i<$count; $i++)
        {
                my $entry=$result->entry($i);
      if(!$entry)
      {
         warn("LDAP: Failed to get record ".$entry." data");
         last LDAP_BLOCK;
      }
                my $name=$entry->get_value(LDAP_ATTRIB);

                if( (!$name) or (!length($name)))
                {
                        warn "LDAP: Skipped record $i"
                          if(DEBUG_LDAP);
                        next NAME_LOOP;
                }
                warn "LDAP: Adding $name"
                  if(DEBUG_LDAP);
                my @sname=split '@', $name;
                if( (scalar(@sname)!=2) || (!length($sname[0])) || (!length($sname[1]))   )
                {
                        warn "LDAP: Skipped record $i due to bad name: $name";
                        next NAME_LOOP;
                }
                system("ejabberdctl", "srg-user-add", $sname[0], $sname[1], GROUP_NAME, SERVER_NAME);
        }

}
$ldap->unbind;

Documentation of schema

Hello,

I'm using ejabberd with an openldap serveur, I can authenticate users, get vcard_ldap and now I want to manage my shared rosters in LDAP.

- I have groupofUniqueNames in the ou=groups,dc=mydomaine,dc=tld.
- Each group has several uniqueMember with dn of users.
- Each users can be in more than one group.

I didn't manage to get mod_shared_roster_ldap working and I wonder if it's possible to have some documentation about how it works.

Regards.

No LDAP request

Hello,

I'm back, with more tests, I see in wireshark that no LDAP request is done when a user connect to the ejabberd server :-/, except for authentication.

My configuration:

{mod_shared_roster_ldap,
  [{ldap_base, "<mybase>"},
   {ldap_groupattr, "cn"},
   {ldap_groupdesc, "cn"},
   {ldap_memberattr, "uniqueMember"},
   {ldap_memberattr_format, "uid=%u*"},
   {ldap_filter, "(uniqueMember=*)}
  ]},

My groups look like:

ou=TECH,ou=groups,<mybase>
objectClass: top
objectClass: groupOfUniqueNames
cn: TECH
uniqueMember: uid=me,ou=People,<mybase>
uniqueMember: uid=boss,ou=Pople,<mybase>

Any idea how to debug an ejabberd module ?

Regards.

Example of debugging prints

dad wrote:

Any idea how to debug an ejabberd module ?

The first thing is to look at ejabberd.log and sasl.log, not only when a user tries to connect but also when ejabberd is started, because maybe they show some info.

You can add your own debugging messages, for example try this:

start(Host, Opts) ->
	io:format("~n--- Hey, we are executing 'start'.  ~n", []),
	io:format("~n    the value of host is: ~p  ~n", [Host]),
	Proc = gen_mod:get_module_proc(Host, ?MODULE),
	ChildSpec = {
		Proc, {?MODULE, start_link, [Host, Opts]},
		permanent, 1000, worker, [?MODULE]
	},
	supervisor:start_child(ejabberd_sup, ChildSpec).

The messages are logged in ejabberd.log.

No logs

badlop wrote:

The first thing is to look at ejabberd.log and sasl.log, not only when a user tries to connect but also when ejabberd is started, because maybe they show some info.

That's the problem, nothing strange in sasl.log when ejabberd starts:

=PROGRESS REPORT==== 18-Feb-2008::11:31:54 ===
          supervisor: {local,ejabberd_sup}
             started: [{pid,<0.208.0>},
                       {name,'mod_shared_roster_ldap_tatooine.example.com'},
                       {mfa,
                           {mod_shared_roster_ldap,
                               start_link,
                               ["tatooine.example.com",
                                [{ldap_memberattr,"uniqueMember"},
                                 {ldap_memberattr_format,"uid=%u*"},
                                 {ldap_filter,"(uniqueMember=*)"}]]}},
                       {restart_type,permanent},
                       {shutdown,1000},
                       {child_type,worker}]

Nothing more in ejabberd.log, even when I added the log message you give me.

I wonder why I don't see any LDAP request in wireshark, to search my group membership when I log in.

Even If my configuration about attributes to seach is wrong, I should see some requests, and the only ones I see are authentication requests and vcard_ldap.

Regards.

additional functionality required

This module assume that additional OU like JabberUsers must be created in AD. Also one user can't be in more than one group (may be have more records one user?).
I think, better will use existent groups and users and apply on it skip filter (for groups and users).
Even better for avoid AD massive usage create another shared_roster module, it will read on user connection external file with shared rosters (like other servers do).

For jabberd2+mysql I created python-script. It sync rosters from AD to jabberd2 (without deletion deleted users).

#!/usr/bin/python
# -*- coding: utf8 -*-
import os, ldap, MySQLdb

ignore = ('all', 'stats', 'controller', 'commerce', 'abonent', 'check_engine', 'technics', 'ao', 'info', 'resume')
bind_user = "CN=jabberd2,DC=example,DC=org"
bind_password = "thepassword"
base = "OU=Office,DC=example,DC=org"

l = ldap.initialize("ldap://AD.AD.AD.AD:389")
l.simple_bind_s(bind_user, bind_password)

persons = {}
for dn, attr in l.search_s(base, ldap.SCOPE_SUBTREE, filterstr='(objectClass=person)', attrlist=('userPrincipalName', 'displayName')):
    if attr.has_key('userPrincipalName'):
        persons[dn] = (attr['userPrincipalName'][0], attr['displayName'][0])

groups = []
for dn,attr in l.search_s(base, ldap.SCOPE_SUBTREE, filterstr='(objectClass=group)', attrlist=('cn', 'member', 'description')):
    members = []
    if attr.has_key('description'):
        for member in attr['member']:
            if (persons.has_key(member)) and (persons[member][0].strip() != ''):
                members.append(persons[member])
        if (len(members) > 0) and (attr['cn'][0].lower() not in ignore):
            groups.append( (attr['cn'][0], attr['description'][0], members) )

con = MySQLdb.connect(host='localhost',user='jabberd2',passwd='thepassword',db='jabberd2')
c = con.cursor()
c.execute('SET NAMES UTF8')
groups.sort(cmp=lambda x,y: cmp(x[1].lower(), y[1].lower()))

rg = {}
c.execute('SELECT `collection-owner`, `jid`, `group` FROM  `roster-groups`')
for row in c:
    if not rg.has_key(row[0]):
        rg[row[0]] = {row[1]: [row[2]]}
    else:
        if not rg[row[0]].has_key(row[1]):
            rg[row[0]][row[1]] = [row[2]]
        else:
            rg[row[0]][row[1]].append(row[2])
ri = {}
c.execute('SELECT `collection-owner`, `jid` FROM `roster-items`')
for row in c:
    if not ri.has_key(row[0]):
        ri[row[0]] = {row[1]: 1}
    else:
        ri[row[0]][row[1]] = 1

cg, ci = 0, 0
for p in persons.itervalues():
    for g in groups:
        for member in g[2]:
            if p[0] != member[0]:
                if not (rg.has_key(p[0]) and rg[p[0]].has_key(member[0]) and (g[1] in rg[p[0]][member[0]])):
                    c.execute('INSERT INTO `roster-groups` (`collection-owner`, `jid`, `group`) VALUES (%s, %s, %s)', (p[0], member[0], g[1]))
                    cg += 1
                if not (ri.has_key(p[0]) and ri[p[0]].has_key(member[0])):
                    c.execute('INSERT INTO `roster-items` (`collection-owner`, `jid`, `name`, `to`, `from`, `ask`) VALUES (%s, %s, %s, 1, 1, 0)', (p[0], member[0], member[1]))
                    if not ri.has_key(p[0]):
                        ri[p[0]] = {member[0]: 1}
                    else:
                        ri[p[0]][member[0]] = 1
                    ci += 1
con.close()
print 'added groups=%d items=%d'%(cg, ci)

I'm not familar with erlang and can't do the task. But I can save instead of MySQL rosters in any format (ex: erlang native lists).

mod_shared_roster_ldap configuration options

I followed tips from
http://www.ejabberd.im/compile-module-windows
to get mod_shared_roster_ldap into my from-binary linux ejabberd installation. So now it's at least into my installation, but I also don't yet have it working.

There seems to be a question of how to do configuration. I also can't read Russian, but I can read code.

Here's what I was able to deduce from reading mod_shared_ldap.erl, specifically, the section that starts with "parse_options". Once you get to that part of the code, try searching for "get_local_option". The options have rather descriptive names, like "ldap_servers", and "ldap_port". Here's the list as I was able to discern from the code...

ldap_servers
ldap_port
ldap_base
ldap_memberattr
ldap_memberattr_format
ldap_rootdn
ldap_password
ldap_filter
ldap_rfilter

I'm still playing with getting this working in my environment. I'll post results and my configuration settings, and of course whether it's working for me or not. So far, the answer is no, but I have more guesses to try.

Try this (in

Try this (in Russian)
http://realloc.spb.ru/share/ejabberd112ad.html

Automaticaly translated by Google:
http://translate.google.com/translate?u=http://realloc.spb.ru/share/ejabberd112ad.html&hl=en&langpair=ru|en&tbb=1&ie=UTF-8

config

Here is my config file :

  {mod_shared_roster_ldap,
  [ {ldap_servers, ["LDAP_SERVER"]},
        {ldap_rootdn, "ROOTDN"},
        {ldap_password, "PASSWD"} ]
  }.

Now, I'm wondering how to configure it ;-)

Configuration in russian

I know a little bit of russian, but not enough to translate that : http://realloc.spb.ru/share/ejabberd112ad.html properly...

------------------------------

Настройка SharedRoster

Надо собрать модуль mod_shared_roster_ldap, на который давалась ссылка выше, и прописать его с указанием атрибутов, по которым будет строиться ростер.

{mod_shared_roster_ldap,
   [{ldap_groupattr,"department"},
    {ldap_groupdesc,"department"},
    {ldap_rfilter, "(&(memberOf=CN=JabberUsers,CN=Users,DC=maya,DC=ku3)(|(userAccountControl=66050)(userAccountControl=66048)))"},
    {ldap_memberattr,"sAMAccountName"},
    {ldap_userdesc,"cn"}
   ]
  },

Настройка клиента

Для авторизации нам необходимо иметь пароль в открытом виде. Поэтому надо в клиенте разрешить передачу пароля незашифрованным. Если использовать SSL, то ничего страшного в этой опции нету.

Did you try with online translators?

Ju. wrote:

I know a little bit of russian, but not enough to translate that

Did you try with online translators?

Syndicate content