New option support: ldap_deref_aliases (EJAB-639)

Conflicts:

	src/ejabberd_auth_ldap.erl
This commit is contained in:
Evgeniy Khramtsov 2011-09-19 16:58:55 +10:00
parent 8b45ee5208
commit f3f80ea0ea
6 changed files with 67 additions and 17 deletions

View File

@ -2355,6 +2355,7 @@ the value previously stored in the database will be used instead of the default
is~\term{""} which means `anonymous connection'. is~\term{""} which means `anonymous connection'.
\titem{\{ldap\_password, Password\}} \ind{options!ldap\_password}Bind password. The default \titem{\{ldap\_password, Password\}} \ind{options!ldap\_password}Bind password. The default
value is \term{""}. value is \term{""}.
\titem{\{ldap\_deref\_aliases, never|always|finding|searching\}} \ind{options!ldap\_deref\_aliases} Whether or not to dereference aliases. The default is \term{never}.
\end{description} \end{description}
Example: Example:
@ -4783,8 +4784,9 @@ The \modvcardldap{} module has
its own optional parameters. The first group of parameters has the same its own optional parameters. The first group of parameters has the same
meaning as the top-level LDAP parameters to set the authentication method: meaning as the top-level LDAP parameters to set the authentication method:
\option{ldap\_servers}, \option{ldap\_port}, \option{ldap\_rootdn}, \option{ldap\_servers}, \option{ldap\_port}, \option{ldap\_rootdn},
\option{ldap\_password}, \option{ldap\_base}, \option{ldap\_uids}, and \option{ldap\_password}, \option{ldap\_base}, \option{ldap\_uids},
\option{ldap\_filter}. See section~\ref{ldapauth} for detailed information \option{ldap\_deref\_aliases} and \option{ldap\_filter}.
See section~\ref{ldapauth} for detailed information
about these options. If one of these options is not set, \ejabberd{} will look about these options. If one of these options is not set, \ejabberd{} will look
for the top-level option with the same name. for the top-level option with the same name.

View File

@ -74,6 +74,7 @@
uids, uids,
ufilter, ufilter,
lfilter, %% Local filter (performed by ejabberd, not LDAP) lfilter, %% Local filter (performed by ejabberd, not LDAP)
deref_aliases,
dn_filter, dn_filter,
dn_filter_attrs dn_filter_attrs
}). }).
@ -352,9 +353,11 @@ get_vh_registered_users_ldap(Server) ->
ResAttrs = result_attrs(State), ResAttrs = result_attrs(State),
case eldap_filter:parse(SearchFilter) of case eldap_filter:parse(SearchFilter) of
{ok, EldapFilter} -> {ok, EldapFilter} ->
case eldap_pool:search(Eldap_ID, [{base, State#state.base}, case eldap_pool:search(Eldap_ID,
[{base, State#state.base},
{filter, EldapFilter}, {filter, EldapFilter},
{timeout, ?LDAP_SEARCH_TIMEOUT}, {timeout, ?LDAP_SEARCH_TIMEOUT},
{deref_aliases, State#state.deref_aliases},
{attributes, ResAttrs}]) of {attributes, ResAttrs}]) of
#eldap_search_result{entries = Entries} -> #eldap_search_result{entries = Entries} ->
lists:flatmap( lists:flatmap(
@ -411,8 +414,10 @@ find_user_dn(User, Server, State) ->
UserFilter = build_ufilter(State, Server), UserFilter = build_ufilter(State, Server),
case eldap_filter:parse(UserFilter, [{"%u", User}]) of case eldap_filter:parse(UserFilter, [{"%u", User}]) of
{ok, Filter} -> {ok, Filter} ->
case eldap_pool:search(State#state.eldap_id, [{base, State#state.base}, case eldap_pool:search(State#state.eldap_id,
[{base, State#state.base},
{filter, Filter}, {filter, Filter},
{deref_aliases, State#state.deref_aliases},
{attributes, ResAttrs}]) of {attributes, ResAttrs}]) of
#eldap_search_result{entries = [#eldap_entry{attributes = Attrs, #eldap_search_result{entries = [#eldap_entry{attributes = Attrs,
object_name = DN} | _]} -> object_name = DN} | _]} ->
@ -453,6 +458,7 @@ is_valid_dn(DN, Server, Attrs, State) ->
case eldap_pool:search(State#state.eldap_id, case eldap_pool:search(State#state.eldap_id,
[{base, State#state.base}, [{base, State#state.base},
{filter, EldapFilter}, {filter, EldapFilter},
{deref_aliases, State#state.deref_aliases},
{attributes, ["dn"]}]) of {attributes, ["dn"]}]) of
#eldap_search_result{entries = [_|_]} -> #eldap_search_result{entries = [_|_]} ->
DN; DN;
@ -564,6 +570,11 @@ parse_options(Host) ->
end, end,
eldap_utils:check_filter(DNFilter), eldap_utils:check_filter(DNFilter),
LocalFilter = ejabberd_config:get_local_option({ldap_local_filter, Host}), LocalFilter = ejabberd_config:get_local_option({ldap_local_filter, Host}),
DerefAliases = case ejabberd_config:get_local_option(
{ldap_deref_aliases, Host}) of
undefined -> never;
Val -> Val
end,
#state{host = Host, #state{host = Host,
eldap_id = Eldap_ID, eldap_id = Eldap_ID,
bind_eldap_id = Bind_Eldap_ID, bind_eldap_id = Bind_Eldap_ID,
@ -580,6 +591,7 @@ parse_options(Host) ->
uids = UIDs, uids = UIDs,
ufilter = UserFilter, ufilter = UserFilter,
lfilter = LocalFilter, lfilter = LocalFilter,
deref_aliases = DerefAliases,
dn_filter = DNFilter, dn_filter = DNFilter,
dn_filter_attrs = DNFilterAttrs dn_filter_attrs = DNFilterAttrs
}. }.

View File

@ -322,6 +322,14 @@ parse_search_args([{timeout, Timeout}|T],A) when is_integer(Timeout) ->
parse_search_args(T,A#eldap_search{timeout = Timeout}); parse_search_args(T,A#eldap_search{timeout = Timeout});
parse_search_args([{limit, Limit}|T],A) when is_integer(Limit) -> parse_search_args([{limit, Limit}|T],A) when is_integer(Limit) ->
parse_search_args(T,A#eldap_search{limit = Limit}); parse_search_args(T,A#eldap_search{limit = Limit});
parse_search_args([{deref_aliases, never}|T],A) ->
parse_search_args(T,A#eldap_search{deref_aliases = neverDerefAliases});
parse_search_args([{deref_aliases, searching}|T],A) ->
parse_search_args(T,A#eldap_search{deref_aliases = derefInSearching});
parse_search_args([{deref_aliases, finding}|T],A) ->
parse_search_args(T,A#eldap_search{deref_aliases = derefFindingBaseObj});
parse_search_args([{deref_aliases, always}|T],A) ->
parse_search_args(T,A#eldap_search{deref_aliases = derefAlways});
parse_search_args([H|_],_) -> parse_search_args([H|_],_) ->
throw({error,{unknown_arg, H}}); throw({error,{unknown_arg, H}});
parse_search_args([],A) -> parse_search_args([],A) ->
@ -699,7 +707,7 @@ gen_req({search, A}) ->
{searchRequest, {searchRequest,
#'SearchRequest'{baseObject = A#eldap_search.base, #'SearchRequest'{baseObject = A#eldap_search.base,
scope = v_scope(A#eldap_search.scope), scope = v_scope(A#eldap_search.scope),
derefAliases = neverDerefAliases, derefAliases = A#eldap_search.deref_aliases,
sizeLimit = A#eldap_search.limit, sizeLimit = A#eldap_search.limit,
timeLimit = v_timeout(A#eldap_search.timeout), timeLimit = v_timeout(A#eldap_search.timeout),
typesOnly = v_bool(A#eldap_search.types_only), typesOnly = v_bool(A#eldap_search.types_only),

View File

@ -28,6 +28,7 @@
limit = 0, limit = 0,
attributes = [], attributes = [],
types_only = false, types_only = false,
deref_aliases = neverDerefAliases,
timeout = 0}). timeout = 0}).

View File

@ -63,6 +63,7 @@
base, base,
password, password,
uid, uid,
deref_aliases,
group_attr, group_attr,
group_desc, group_desc,
user_desc, user_desc,
@ -330,6 +331,7 @@ eldap_search(State, FilterParseArgs, AttributesList) ->
[{base, State#state.base}, [{base, State#state.base},
{filter, EldapFilter}, {filter, EldapFilter},
{timeout, ?LDAP_SEARCH_TIMEOUT}, {timeout, ?LDAP_SEARCH_TIMEOUT},
{deref_aliases, State#state.deref_aliases},
{attributes, AttributesList}]) of {attributes, AttributesList}]) of
#eldap_search_result{entries = Es} -> #eldap_search_result{entries = Es} ->
%% A result with entries. Return their list. %% A result with entries. Return their list.
@ -671,6 +673,15 @@ parse_options(Host, Opts) ->
"" -> GroupSubFilter; "" -> GroupSubFilter;
_ -> "(&" ++ GroupSubFilter ++ ConfigFilter ++ ")" _ -> "(&" ++ GroupSubFilter ++ ConfigFilter ++ ")"
end, end,
DerefAliases = case gen_mod:get_opt(deref_aliases, Opts, undefined) of
undefined ->
case ejabberd_config:get_local_option(
{deref_aliases, Host}) of
undefined -> never;
D -> D
end;
D -> D
end,
#state{host = Host, #state{host = Host,
eldap_id = Eldap_ID, eldap_id = Eldap_ID,
servers = LDAPServers, servers = LDAPServers,
@ -684,6 +695,7 @@ parse_options(Host, Opts) ->
base = LDAPBase, base = LDAPBase,
password = Password, password = Password,
uid = UIDAttr, uid = UIDAttr,
deref_aliases = DerefAliases,
group_attr = GroupAttr, group_attr = GroupAttr,
group_desc = GroupDesc, group_desc = GroupDesc,
user_desc = UserDesc, user_desc = UserDesc,

View File

@ -75,6 +75,7 @@
search_fields, search_fields,
search_reported, search_reported,
search_reported_attrs, search_reported_attrs,
deref_aliases,
matches matches
}). }).
@ -285,8 +286,10 @@ find_ldap_user(User, State) ->
VCardAttrs = State#state.vcard_map_attrs, VCardAttrs = State#state.vcard_map_attrs,
case eldap_filter:parse(RFC2254_Filter, [{"%u", User}]) of case eldap_filter:parse(RFC2254_Filter, [{"%u", User}]) of
{ok, EldapFilter} -> {ok, EldapFilter} ->
case eldap_pool:search(Eldap_ID, [{base, Base}, case eldap_pool:search(Eldap_ID,
[{base, Base},
{filter, EldapFilter}, {filter, EldapFilter},
{deref_aliases, State#state.deref_aliases},
{attributes, VCardAttrs}]) of {attributes, VCardAttrs}]) of
#eldap_search_result{entries = [E | _]} -> #eldap_search_result{entries = [E | _]} ->
E; E;
@ -557,9 +560,11 @@ search(State, Data) ->
Limit = State#state.matches, Limit = State#state.matches,
ReportedAttrs = State#state.search_reported_attrs, ReportedAttrs = State#state.search_reported_attrs,
Filter = eldap:'and'([SearchFilter, eldap_utils:make_filter(Data, UIDs)]), Filter = eldap:'and'([SearchFilter, eldap_utils:make_filter(Data, UIDs)]),
case eldap_pool:search(Eldap_ID, [{base, Base}, case eldap_pool:search(Eldap_ID,
[{base, Base},
{filter, Filter}, {filter, Filter},
{limit, Limit}, {limit, Limit},
{deref_aliases, State#state.deref_aliases},
{attributes, ReportedAttrs}]) of {attributes, ReportedAttrs}]) of
#eldap_search_result{entries = E} -> #eldap_search_result{entries = E} ->
search_items(E, State); search_items(E, State);
@ -760,6 +765,15 @@ parse_options(Host, Opts) ->
_ -> [] _ -> []
end end
end, SearchReported) ++ UIDAttrs), end, SearchReported) ++ UIDAttrs),
DerefAliases = case gen_mod:get_opt(deref_aliases, Opts, undefined) of
undefined ->
case ejabberd_config:get_local_option(
{deref_aliases, Host}) of
undefined -> never;
D -> D
end;
D -> D
end,
#state{serverhost = Host, #state{serverhost = Host,
myhost = MyHost, myhost = MyHost,
eldap_id = Eldap_ID, eldap_id = Eldap_ID,
@ -782,5 +796,6 @@ parse_options(Host, Opts) ->
search_fields = SearchFields, search_fields = SearchFields,
search_reported = SearchReported, search_reported = SearchReported,
search_reported_attrs = SearchReportedAttrs, search_reported_attrs = SearchReportedAttrs,
deref_aliases = DerefAliases,
matches = Matches matches = Matches
}. }.