]> 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 07:03:36 +0000 (17:03 +1000)
Conflicts:

src/ejabberd_auth_ldap.erl

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 28be76c66a7e33df02ba39a9971ba79802786e74..e4d4c9264e18e0651e76723faa28065a9794b41d 100644 (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'.
 \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:
@@ -4783,8 +4784,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 5db6187e12d2e40ee4e4354c17846433b7c66fef..5395df197e67ebd567f3712e654364b326524052 100644 (file)
@@ -74,6 +74,7 @@
                uids,
                ufilter,
                lfilter, %% Local filter (performed by ejabberd, not LDAP)
+                deref_aliases,
                dn_filter,
                dn_filter_attrs
               }).
@@ -352,10 +353,12 @@ get_vh_registered_users_ldap(Server) ->
     ResAttrs = result_attrs(State),
     case eldap_filter:parse(SearchFilter) 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,
@@ -411,9 +414,11 @@ find_user_dn(User, Server, State) ->
     UserFilter = build_ufilter(State, Server),
     case eldap_filter:parse(UserFilter, [{"%u", User}]) of
        {ok, Filter} ->
-           case eldap_pool:search(State#state.eldap_id, [{base, State#state.base},
-                                                    {filter, Filter},
-                                                    {attributes, ResAttrs}]) of
+           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} | _]} ->
                        dn_filter(DN, Server, Attrs, State);
@@ -453,6 +458,7 @@ is_valid_dn(DN, Server, Attrs, State) ->
            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;
@@ -564,6 +570,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,
@@ -580,6 +591,7 @@ parse_options(Host) ->
           uids = UIDs,
           ufilter = UserFilter,
           lfilter = LocalFilter,
+           deref_aliases = DerefAliases,
           dn_filter = DNFilter,
           dn_filter_attrs = DNFilterAttrs
          }.
index f14c8aca623c06040bd417d00e54fc7060618edf..fb7e264c3a364125f159cebfd1ddd102df80a8d6 100644 (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([{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) ->
@@ -699,7 +707,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 0e1ce887de29e091cb692569a1f475153b42bab1..e5aa4c64ecf1d19e0459aed757eecfaec1823ce6 100644 (file)
@@ -63,6 +63,7 @@
                base,
                password,
                uid,
+                deref_aliases,
                group_attr,
                group_desc,
                user_desc,
@@ -330,6 +331,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.
@@ -671,6 +673,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,
@@ -684,6 +695,7 @@ parse_options(Host, Opts) ->
           base = LDAPBase,
           password = Password,
           uid = UIDAttr,
+           deref_aliases = DerefAliases,
           group_attr = GroupAttr,
           group_desc = GroupDesc,
           user_desc = UserDesc,
index 4a7d1ef76d222e89e508c7c11b982c2b940e749c..ee580085f51ae1fb70f7c9ff35b9d478b13ef3e6 100644 (file)
@@ -75,6 +75,7 @@
                search_fields,
                search_reported,
                search_reported_attrs,
+                deref_aliases,
                matches
               }).
 
@@ -285,9 +286,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;
                _ ->
@@ -557,10 +560,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);
        _ ->
@@ -760,6 +765,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,
@@ -782,5 +796,6 @@ parse_options(Host, Opts) ->
           search_fields = SearchFields,
           search_reported = SearchReported,
           search_reported_attrs = SearchReportedAttrs,
+           deref_aliases = DerefAliases,
           matches = Matches
          }.