]> granicus.if.org Git - ejabberd/commitdiff
New option support: ldap_deref_aliases (EJAB-639)
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Mon, 19 Sep 2011 06:58:55 +0000 (16:58 +1000)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Mon, 19 Sep 2011 06:58:55 +0000 (16:58 +1000)
doc/guide.tex
src/ejabberd_auth_ldap.erl
src/eldap/eldap.erl
src/eldap/eldap.hrl
src/mod_shared_roster_ldap.erl
src/mod_vcard_ldap.erl

index 5e3ce7d255e400ba0828ffb232619d610073bbab..afbbbd99768250b742c5302921298e7fdcdec054 100644 (file)
@@ -2303,6 +2303,7 @@ the value previously stored in the database will be used instead of the default
   is~\term{""} which means `anonymous connection'.
 \titem{\{ldap\_password, Password\}} \ind{options!ldap\_password}Bind password. The default
   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}
 
 Example:
@@ -4689,8 +4690,9 @@ The \modvcardldap{} module has
 its own optional parameters. The first group of parameters has the same
 meaning as the top-level LDAP parameters to set the authentication method:
 \option{ldap\_servers}, \option{ldap\_port}, \option{ldap\_rootdn},
-\option{ldap\_password}, \option{ldap\_base}, \option{ldap\_uids}, and
-\option{ldap\_filter}. See section~\ref{ldapauth} for detailed information
+\option{ldap\_password}, \option{ldap\_base}, \option{ldap\_uids},
+\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
 for the top-level option with the same name.
 
index 77216a1cd95a1309517643baa912eb1afe6eaf05..54a346c07c019923f233288c159650f25e533365 100644 (file)
@@ -75,6 +75,7 @@
                ufilter,
                sfilter,
                lfilter, %% Local filter (performed by ejabberd, not LDAP)
+                deref_aliases,
                dn_filter,
                dn_filter_attrs
               }).
@@ -230,10 +231,12 @@ get_vh_registered_users_ldap(Server) ->
     ResAttrs = result_attrs(State),
     case eldap_filter:parse(State#state.sfilter) of
                {ok, EldapFilter} ->
-                   case eldap_pool:search(Eldap_ID, [{base, State#state.base},
-                                                {filter, EldapFilter},
-                                                {timeout, ?LDAP_SEARCH_TIMEOUT},
-                                                {attributes, ResAttrs}]) of
+                   case eldap_pool:search(Eldap_ID,
+                                           [{base, State#state.base},
+                                            {filter, EldapFilter},
+                                            {timeout, ?LDAP_SEARCH_TIMEOUT},
+                                            {deref_aliases, State#state.deref_aliases},
+                                            {attributes, ResAttrs}]) of
                        #eldap_search_result{entries = Entries} ->
                            lists:flatmap(
                              fun(#eldap_entry{attributes = Attrs,
@@ -285,6 +288,7 @@ find_user_dn(User, State) ->
            case eldap_pool:search(State#state.eldap_id,
                                   [{base, State#state.base},
                                    {filter, Filter},
+                                    {deref_aliases, State#state.deref_aliases},
                                    {attributes, ResAttrs}]) of
                #eldap_search_result{entries = [#eldap_entry{attributes = Attrs,
                                                             object_name = DN} | _]} ->
@@ -322,10 +326,11 @@ is_valid_dn(DN, Attrs, State) ->
                  end ++ [{"%d", State#state.host}, {"%D", DN}],
     case eldap_filter:parse(State#state.dn_filter, SubstValues) of
        {ok, EldapFilter} ->
-           case eldap_pool:search(State#state.eldap_id, [
-                                                    {base, State#state.base},
-                                                    {filter, EldapFilter},
-                                                    {attributes, ["dn"]}]) of
+           case eldap_pool:search(State#state.eldap_id,
+                                   [{base, State#state.base},
+                                    {filter, EldapFilter},
+                                    {deref_aliases, State#state.deref_aliases},
+                                    {attributes, ["dn"]}]) of
                #eldap_search_result{entries = [_|_]} ->
                    DN;
                _ ->
@@ -421,6 +426,11 @@ parse_options(Host) ->
        end,
     eldap_utils:check_filter(DNFilter),
     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,
           eldap_id = Eldap_ID,
           bind_eldap_id = Bind_Eldap_ID,
@@ -438,6 +448,7 @@ parse_options(Host) ->
           ufilter = UserFilter,
           sfilter = SearchFilter,
           lfilter = LocalFilter,
+           deref_aliases = DerefAliases,
           dn_filter = DNFilter,
           dn_filter_attrs = DNFilterAttrs
          }.
index a134a4c9517868817b317241dd6e58d186b0dc03..aa22e1849f6a145bf6403d4448716089f0cb15ba 100644 (file)
@@ -323,6 +323,14 @@ parse_search_args([{timeout, Timeout}|T],A) when is_integer(Timeout) ->
     parse_search_args(T,A#eldap_search{timeout = Timeout});
 parse_search_args([{limit, Limit}|T],A) when is_integer(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|_],_) ->
     throw({error,{unknown_arg, H}});
 parse_search_args([],A) ->
@@ -700,7 +708,7 @@ gen_req({search, A}) ->
     {searchRequest,
      #'SearchRequest'{baseObject   = A#eldap_search.base,
                      scope        = v_scope(A#eldap_search.scope),
-                     derefAliases = neverDerefAliases,
+                     derefAliases = A#eldap_search.deref_aliases,
                      sizeLimit    = A#eldap_search.limit,
                      timeLimit    = v_timeout(A#eldap_search.timeout),
                      typesOnly    = v_bool(A#eldap_search.types_only),
index 5436fa794ee451c0122f3321355b294dd9127d47..23b4984351b70b0a86f299149d3a87e08a498734 100644 (file)
@@ -28,6 +28,7 @@
                       limit = 0,
                       attributes = [],
                       types_only = false,
+                       deref_aliases = neverDerefAliases,
                       timeout = 0}).
 
 
index 0e1143d4a699186af0a4243c069ca3aacbb7a3f7..04e90dd4d52bf9974d7116e1b65a51e3705cac9e 100644 (file)
@@ -63,6 +63,7 @@
                base,
                password,
                uid,
+                deref_aliases,
                group_attr,
                group_desc,
                user_desc,
@@ -314,6 +315,7 @@ eldap_search(State, FilterParseArgs, AttributesList) ->
                                   [{base, State#state.base},
                                    {filter, EldapFilter},
                                    {timeout, ?LDAP_SEARCH_TIMEOUT},
+                                    {deref_aliases, State#state.deref_aliases},
                                    {attributes, AttributesList}]) of
                 #eldap_search_result{entries = Es} ->
                    %% A result with entries. Return their list.
@@ -659,6 +661,15 @@ parse_options(Host, Opts) ->
                      "" -> GroupSubFilter;
                      _ -> "(&" ++ GroupSubFilter ++ ConfigFilter ++ ")"
                  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,
           eldap_id = Eldap_ID,
           servers = LDAPServers,
@@ -672,6 +683,7 @@ parse_options(Host, Opts) ->
           base = LDAPBase,
           password = Password,
           uid = UIDAttr,
+           deref_aliases = DerefAliases,
           group_attr = GroupAttr,
           group_desc = GroupDesc,
           user_desc = UserDesc,
index 56ba9eb4d278d83e453ede125331ea95d9c0e453..03c00f628f3fbd5709623456dc07b25b92743ac6 100644 (file)
@@ -74,6 +74,7 @@
                search_fields,
                search_reported,
                search_reported_attrs,
+                deref_aliases,
                matches
               }).
 
@@ -287,9 +288,11 @@ find_ldap_user(User, State) ->
     VCardAttrs = State#state.vcard_map_attrs,
     case eldap_filter:parse(RFC2254_Filter, [{"%u", User}]) of
        {ok, EldapFilter} ->
-           case eldap_pool:search(Eldap_ID, [{base, Base},
-                                        {filter, EldapFilter},
-                                        {attributes, VCardAttrs}]) of
+           case eldap_pool:search(Eldap_ID,
+                                   [{base, Base},
+                                    {filter, EldapFilter},
+                                    {deref_aliases, State#state.deref_aliases},
+                                    {attributes, VCardAttrs}]) of
                #eldap_search_result{entries = [E | _]} ->
                    E;
                _ ->
@@ -572,10 +575,12 @@ search(State, Data) ->
     Limit = State#state.matches,
     ReportedAttrs = State#state.search_reported_attrs,
     Filter = eldap:'and'([SearchFilter, eldap_utils:make_filter(Data, UIDs)]),
-    case eldap_pool:search(Eldap_ID, [{base, Base},
-                                {filter, Filter},
-                                {limit, Limit},
-                                {attributes, ReportedAttrs}]) of
+    case eldap_pool:search(Eldap_ID,
+                           [{base, Base},
+                            {filter, Filter},
+                            {limit, Limit},
+                            {deref_aliases, State#state.deref_aliases},
+                            {attributes, ReportedAttrs}]) of
        #eldap_search_result{entries = E} ->
            search_items(E, State);
        _ ->
@@ -779,6 +784,15 @@ parse_options(Host, Opts) ->
                                  _ -> []
                              end
                      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,
           myhost = MyHost,
           eldap_id = Eldap_ID,
@@ -801,5 +815,6 @@ parse_options(Host, Opts) ->
           search_fields = SearchFields,
           search_reported = SearchReported,
           search_reported_attrs = SearchReportedAttrs,
+           deref_aliases = DerefAliases,
           matches = Matches
          }.