Troubleshooting Ejabberd Mod_shared_roster_ldap Unintended User Population

by Sharif Sakr 75 views

Hey guys! Today, we're diving deep into an intriguing issue encountered while using mod_shared_roster_ldap in ejabberd. Specifically, we'll be discussing a scenario where the shared roster is populated with users who don't match the intended criteria. This can be a real head-scratcher, especially when you've got different types of users in your LDAP directory, like "persons" and "virtual" users. So, let's break down the problem, explore the configuration, and figure out the best way to tackle this. We will explore how to configure mod_shared_roster_ldap in ejabberd to avoid unintended user population.

Environment Overview

Before we jump into the nitty-gritty, let's quickly run through the environment setup. The user is running ejabberd version 24.10, backed by Erlang version 14.2.1, on a Linux (Gentoo) system. They've installed ejabberd from a distro package, which is a pretty standard setup. Knowing the environment helps us understand the context and potential constraints we might face while troubleshooting. Now, let's get to the heart of the matter – the configuration.

Configuration Details

Let's take a closer look at the ejabberd.yml configuration file. This is where the magic happens, and it's crucial to understand how the modules are configured to effectively troubleshoot the issue. The relevant parts of the configuration are:

auth_method:
  - ldap
..
ldap_filter: "(objectClass=x-local-users-xmpp)"
ldap_uids:
  jid: "%u@%d"
..
mod_shared_roster_ldap:
  ldap_useruid: "uid"
  ldap_filter: "(&(objectClass=x-local-users-person)(objectClass=x-local-users-xmpp))"
  ldap_rfilter: "(objectClass=x-local-domains)"
  ldap_ufilter: "(uid=%u)"
  ldap_gfilter: "(ou=%g)"
  ldap_groupattr: "ou"
  ldap_groupdesc: "o"
  ldap_memberattr: "uid"
  ldap_userdesc: "cn"
...

Here's a breakdown of the key parameters:

  • auth_method: Specifies that LDAP is used for authentication.
  • ldap_filter: This filter (objectClass=x-local-users-xmpp) is used for general LDAP user retrieval. This is a critical setting as it defines which users ejabberd considers as valid XMPP users.
  • ldap_uids: Defines how JIDs (Jabber Identifiers) are constructed, using the username (%u) and domain (%d). This ensures that users are correctly identified within the XMPP system.
  • mod_shared_roster_ldap: This section configures the shared roster functionality using LDAP. This is where the core issue lies, so let's dissect it further:
    • ldap_useruid: Specifies the LDAP attribute to use as the user ID (uid).
    • ldap_filter: This is the main filter for shared roster users: (&(objectClass=x-local-users-person)(objectClass=x-local-users-xmpp)). It aims to include only users who are both "persons" and have XMPP enabled.
    • ldap_rfilter: Filters for domains ((objectClass=x-local-domains)).
    • ldap_ufilter: Filters for individual users ((uid=%u)).
    • ldap_gfilter: Filters for groups ((ou=%g)).
    • ldap_groupattr: Specifies the attribute for group names (ou).
    • ldap_groupdesc: Specifies the attribute for group descriptions (o).
    • ldap_memberattr: Specifies the attribute for group members (uid).
    • ldap_userdesc: Specifies the attribute for user descriptions (cn).

The crucial part here is the ldap_filter within the mod_shared_roster_ldap section. It’s designed to fetch users who have both x-local-users-person and x-local-users-xmpp object classes. However, the problem arises because “virtual” users also have the x-local-users-xmpp object class, causing them to be included in the shared roster, which is not the desired outcome.

LDAP Structure

To fully grasp the issue, let's visualize the LDAP structure. We have two main types of users:

  • Person Users:

    dn: uid=test1,ou=example.com,dc=local
    objectClass: x-local-users-person
    objectClass: x-local-users-xmpp
    ou: example.com
    jid: test1@example.com
    uid: test1
    mail: test1@example.com
    
    dn: uid=test2,ou=example.com,dc=local
    objectClass: x-local-users-person
    objectClass: x-local-users-xmpp
    ou: example.com
    jid: test2@example.com
    uid: test2
    mail: test2@example.com
    
  • Virtual Users:

    dn: uid=security,ou=example.com,dc=local
    objectClass: x-local-users-virtual
    objectClass: x-local-users-xmpp
    ou: example.com
    jid: security@example.com
    uid: security
    

As you can see, both types of users share the x-local-users-xmpp object class. This is why the current ldap_filter in mod_shared_roster_ldap includes both “person” and “virtual” users. The goal is to modify the filter to differentiate between these user types so that only “person” users appear in the shared roster for “person” users, and “virtual” users have an empty roster.

The Problem: Unintended User Population

The core issue here is that the shared roster includes