summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorethoms <euan@potensol.com>2020-12-31 17:19:43 +0800
committerGitHub <noreply@github.com>2020-12-31 10:19:43 +0100
commitcdb286d1d1360c8b8caa58fc27381db9a06775a2 (patch)
treed782816b1666eaba382d78f222b09ad62a95a30d /src
parentJWT enhancement (#3460) (diff)
Add multi-domain support (and flexibility) to LDAP shared roster (rev2). (#3461)
Diffstat (limited to 'src')
-rw-r--r--src/mod_shared_roster_ldap.erl59
-rw-r--r--src/mod_shared_roster_ldap_opt.erl7
2 files changed, 48 insertions, 18 deletions
diff --git a/src/mod_shared_roster_ldap.erl b/src/mod_shared_roster_ldap.erl
index 3cb20b0b..cdec4b20 100644
--- a/src/mod_shared_roster_ldap.erl
+++ b/src/mod_shared_roster_ldap.erl
@@ -76,7 +76,8 @@
ufilter = <<"">> :: binary(),
rfilter = <<"">> :: binary(),
gfilter = <<"">> :: binary(),
- auth_check = true :: boolean()}).
+ user_jid_attr = <<"">> :: binary(),
+ auth_check = true :: boolean()}).
-record(group_info, {desc, members}).
@@ -387,6 +388,24 @@ search_group_info(State, Group) ->
{ok, #group_info{desc = GroupDesc, members = lists:usort(lists:flatten(MembersLists))}}
end.
+get_member_jid(#state{user_jid_attr = <<>>}, UID, Host) ->
+ {jid:nodeprep(UID), Host};
+get_member_jid(#state{user_jid_attr = UserJIDAttr, user_uid = UIDAttr} = State,
+ UID, Host) ->
+ Entries = eldap_search(State,
+ [eldap_filter:do_sub(<<"(", UIDAttr/binary, "=%u)">>,
+ [{<<"%u">>, UID}])],
+ [UserJIDAttr]),
+ case Entries of
+ [] ->
+ {error, error};
+ [#eldap_entry{attributes = [{UserJIDAttr, [MemberJID | _]}]} | _] ->
+ case jid:decode(MemberJID) of
+ error -> {error, Host};
+ #jid{luser = U, lserver = S} -> {U, S}
+ end
+ end.
+
extract_members(State, Extractor, AuthChecker, #eldap_entry{attributes = Attrs}, {DescAcc, JIDsAcc}) ->
Host = State#state.host,
case {eldap_utils:get_ldap_attr(State#state.group_attr, Attrs),
@@ -394,23 +413,22 @@ extract_members(State, Extractor, AuthChecker, #eldap_entry{attributes = Attrs},
lists:keysearch(State#state.uid, 1, Attrs)} of
{ID, Desc, {value, {GroupMemberAttr, Members}}} when ID /= <<"">>,
GroupMemberAttr == State#state.uid ->
- JIDs = lists:foldl(fun({ok, UID}, L) ->
- PUID = jid:nodeprep(UID),
- case PUID of
- error ->
- L;
- _ ->
- case AuthChecker(PUID, Host) of
- true ->
- [{PUID, Host} | L];
- _ ->
- L
- end
- end;
- (_, L) -> L
- end,
- [],
- lists:map(Extractor, Members)),
+ JIDs = lists:foldl(
+ fun({ok, UID}, L) ->
+ {MemberUID, MemberHost} = get_member_jid(State, UID, Host),
+ case MemberUID of
+ error ->
+ L;
+ _ ->
+ case AuthChecker(MemberUID, MemberHost) of
+ true ->
+ [{MemberUID, MemberHost} | L];
+ _ ->
+ L
+ end
+ end;
+ (_, L) -> L
+ end, [], lists:map(Extractor, Members)),
{Desc, [JIDs | JIDsAcc]};
_ ->
{DescAcc, JIDsAcc}
@@ -456,6 +474,7 @@ parse_options(Host, Opts) ->
UIDAttr = mod_shared_roster_ldap_opt:ldap_memberattr(Opts),
UIDAttrFormat = mod_shared_roster_ldap_opt:ldap_memberattr_format(Opts),
UIDAttrFormatRe = mod_shared_roster_ldap_opt:ldap_memberattr_format_re(Opts),
+ JIDAttr = mod_shared_roster_ldap_opt:ldap_userjidattr(Opts),
AuthCheck = mod_shared_roster_ldap_opt:ldap_auth_check(Opts),
ConfigFilter = mod_shared_roster_ldap_opt:ldap_filter(Opts),
ConfigUserFilter = mod_shared_roster_ldap_opt:ldap_ufilter(Opts),
@@ -500,6 +519,7 @@ parse_options(Host, Opts) ->
base = Cfg#eldap_config.base,
deref_aliases = Cfg#eldap_config.deref_aliases,
uid = UIDAttr,
+ user_jid_attr = JIDAttr,
group_attr = GroupAttr, group_desc = GroupDesc,
user_desc = UserDesc, user_uid = UserUID,
uid_format = UIDAttrFormat,
@@ -551,6 +571,8 @@ mod_opt_type(ldap_userdesc) ->
econf:binary();
mod_opt_type(ldap_useruid) ->
econf:binary();
+mod_opt_type(ldap_userjidattr) ->
+ econf:binary();
mod_opt_type(ldap_backups) ->
econf:list(econf:domain(), [unique]);
mod_opt_type(ldap_base) ->
@@ -607,6 +629,7 @@ mod_options(Host) ->
{ldap_ufilter, <<"">>},
{ldap_userdesc, <<"cn">>},
{ldap_useruid, <<"cn">>},
+ {ldap_userjidattr, <<"">>},
{ldap_backups, ejabberd_option:ldap_backups(Host)},
{ldap_base, ejabberd_option:ldap_base(Host)},
{ldap_uids, ejabberd_option:ldap_uids(Host)},
diff --git a/src/mod_shared_roster_ldap_opt.erl b/src/mod_shared_roster_ldap_opt.erl
index 5703ed0b..3833f24f 100644
--- a/src/mod_shared_roster_ldap_opt.erl
+++ b/src/mod_shared_roster_ldap_opt.erl
@@ -30,6 +30,7 @@
-export([ldap_ufilter/1]).
-export([ldap_uids/1]).
-export([ldap_userdesc/1]).
+-export([ldap_userjidattr/1]).
-export([ldap_useruid/1]).
-export([use_cache/1]).
@@ -195,6 +196,12 @@ ldap_userdesc(Opts) when is_map(Opts) ->
ldap_userdesc(Host) ->
gen_mod:get_module_opt(Host, mod_shared_roster_ldap, ldap_userdesc).
+-spec ldap_userjidattr(gen_mod:opts() | global | binary()) -> binary().
+ldap_userjidattr(Opts) when is_map(Opts) ->
+ gen_mod:get_opt(ldap_userjidattr, Opts);
+ldap_userjidattr(Host) ->
+ gen_mod:get_module_opt(Host, mod_shared_roster_ldap, ldap_userjidattr).
+
-spec ldap_useruid(gen_mod:opts() | global | binary()) -> binary().
ldap_useruid(Opts) when is_map(Opts) ->
gen_mod:get_opt(ldap_useruid, Opts);