aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/eldap/doc/src/eldap.xml12
-rw-r--r--lib/eldap/src/eldap.erl23
-rw-r--r--lib/eldap/test/eldap_basic_SUITE.erl10
3 files changed, 43 insertions, 2 deletions
diff --git a/lib/eldap/doc/src/eldap.xml b/lib/eldap/doc/src/eldap.xml
index dbd478fb17..4417551aa8 100644
--- a/lib/eldap/doc/src/eldap.xml
+++ b/lib/eldap/doc/src/eldap.xml
@@ -48,7 +48,7 @@ scope() See baseObject/0, singleLevel/0, wholeSubtree/0
dereference() See neverDerefAliases/0, derefInSearching/0, derefFindingBaseObj/0, derefAlways/0
filter() See present/1, substrings/2,
equalityMatch/2, greaterOrEqual/2, lessOrEqual/2,
- approxMatch/2,
+ approxMatch/2, extensibleMatch/2,
'and'/1, 'or'/1, 'not'/1.
</pre>
<p></p>
@@ -348,6 +348,16 @@ filter() See present/1, substrings/2,
<desc> <p>Create a approximation match filter.</p> </desc>
</func>
<func>
+ <name>extensibleMatch(MatchValue, OptionalAttrs) -> filter()</name>
+ <fsummary>Create search filter option.</fsummary>
+ <type>
+ <v>MatchValue = string()</v>
+ <v>OptionalAttrs = [Attr]</v>
+ <v>Attr = {matchingRule,string()} | {type,string()} | {dnAttributes,boolean()}</v>
+ </type>
+ <desc> <p>Creates an extensible match filter. For example, <c>eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseExactMatch"}]))</c> creates a filter which performs a <c>caseExactMatch</c> on the attribute <c>sn</c> and matches with the value <c>"Bar"</c>. The default value of <c>dnAttributes</c> is <c>false</c>.</p> </desc>
+ </func>
+ <func>
<name>'and'([Filter]) -> filter()</name>
<fsummary>Create search filter option.</fsummary>
<type>
diff --git a/lib/eldap/src/eldap.erl b/lib/eldap/src/eldap.erl
index 416334e365..3fa440d37d 100644
--- a/lib/eldap/src/eldap.erl
+++ b/lib/eldap/src/eldap.erl
@@ -15,6 +15,7 @@
getopts/2,
baseObject/0,singleLevel/0,wholeSubtree/0,close/1,
equalityMatch/2,greaterOrEqual/2,lessOrEqual/2,
+ extensibleMatch/2,
approxMatch/2,search/2,substrings/2,present/1,
'and'/1,'or'/1,'not'/1,modify/3, mod_add/2, mod_delete/2,
mod_replace/2, add/3, delete/2, modify_dn/5,parse_dn/1,
@@ -350,6 +351,27 @@ substrings(Type, SubStr) when is_list(Type), is_list(SubStr) ->
{substrings,#'SubstringFilter'{type = Type,
substrings = Ss}}.
+%%%
+%%% Filter for extensibleMatch
+%%%
+extensibleMatch(MatchValue, OptArgs) ->
+ MatchingRuleAssertion =
+ mra(OptArgs, #'MatchingRuleAssertion'{matchValue = MatchValue}),
+ {extensibleMatch, MatchingRuleAssertion}.
+
+mra([{matchingRule,Val}|T], Ack) when is_list(Val) ->
+ mra(T, Ack#'MatchingRuleAssertion'{matchingRule=Val});
+mra([{type,Val}|T], Ack) when is_list(Val) ->
+ mra(T, Ack#'MatchingRuleAssertion'{type=Val});
+mra([{dnAttributes,true}|T], Ack) ->
+ mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="TRUE"});
+mra([{dnAttributes,false}|T], Ack) ->
+ mra(T, Ack#'MatchingRuleAssertion'{dnAttributes="FALSE"});
+mra([H|_], _) ->
+ throw({error,{extensibleMatch_arg,H}});
+mra([], Ack) ->
+ Ack.
+
%%% --------------------------------------------------------------------
%%% Worker process. We keep track of a controlling process to
%%% be able to terminate together with it.
@@ -862,6 +884,7 @@ v_filter({lessOrEqual,AV}) -> {lessOrEqual,AV};
v_filter({approxMatch,AV}) -> {approxMatch,AV};
v_filter({present,A}) -> {present,A};
v_filter({substrings,S}) when is_record(S,'SubstringFilter') -> {substrings,S};
+v_filter({extensibleMatch,S}) when is_record(S,'MatchingRuleAssertion') -> {extensibleMatch,S};
v_filter(_Filter) -> throw({error,concat(["unknown filter: ",_Filter])}).
v_modifications(Mods) ->
diff --git a/lib/eldap/test/eldap_basic_SUITE.erl b/lib/eldap/test/eldap_basic_SUITE.erl
index 6c3d303da0..d87f3ac4ac 100644
--- a/lib/eldap/test/eldap_basic_SUITE.erl
+++ b/lib/eldap/test/eldap_basic_SUITE.erl
@@ -106,7 +106,9 @@ api(doc) -> "Basic test that all api functions works as expected";
api(suite) -> [];
api(Config) ->
{Host,Port} = proplists:get_value(ldap_server, Config),
- {ok, H} = eldap:open([Host], [{port,Port}]),
+ {ok, H} = eldap:open([Host], [{port,Port}
+ ,{log,fun(Lvl,Fmt,Args)-> io:format("~p: ~s",[Lvl,io_lib:format(Fmt,Args)]) end}
+ ]),
%% {ok, H} = eldap:open([Host], [{port,Port+1}, {ssl, true}]),
do_api_checks(H, Config),
eldap:close(H),
@@ -232,6 +234,12 @@ chk_search(H, BasePath) ->
{ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(F_AND),
F_NOT = eldap:'and'([eldap:present("objectclass"), eldap:'not'(eldap:present("ou"))]),
{ok, #eldap_search_result{entries=[#eldap_entry{}, #eldap_entry{}]}} = Search(F_NOT),
+ {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseExactMatch"}])),
+ {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"2.5.13.5"}])),
+ {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:extensibleMatch("Bar",[{type,"sn"},{matchingRule,"caseIgnoreMatch"}])),
+ {ok, #eldap_search_result{entries=[#eldap_entry{}]}} = Search(eldap:extensibleMatch("bar",[{type,"sn"},{matchingRule,"caseIgnoreMatch"}])),
+ {ok, #eldap_search_result{entries=[]}} = Search(eldap:extensibleMatch("bar",[{type,"sn"},{matchingRule,"gluffgluff"}])),
+ {ok, #eldap_search_result{entries=[]}} = Search(eldap:extensibleMatch("bar",[{type,"sn"},{matchingRule,"caseExactMatch"}])),
{ok,FB}. %% FIXME
chk_modify(H, FB) ->